3

https://godbolt.org/z/YK5PPvz7d

#include <stdio.h>

struct file_format_a_header 
{
    int i;
};

struct file_format_b_header 
{
    int i;
};

int main()
{
    int type = 1;
    size_t len = 0;

    if (1 == type)
    {
        len = sizeof(struct file_format_a_header ); // sizeof file_format_a_header and file_format_b_header  is SAME but they are different structures
    }
    else
    {
        len = sizeof(struct file_format_b_header );
    }

    printf("len = %zu\n", len);
    return 0;
}


<source>: In function 'main':
<source>:18:8: error: this condition has identical branches [-Werror=duplicated-branches]
   18 |     if (1 == type)
      |        ^
cc1: all warnings being treated as errors
ASM generation compiler returned: 1
<source>: In function 'main':
<source>:18:8: error: this condition has identical branches [-Werror=duplicated-branches]
   18 |     if (1 == type)
      |        ^
cc1: all warnings being treated as errors
Execution build compiler returned: 1

GCC switches:

-std=gnu11
-Wall
-Werror
-Wextra
-Wduplicated-branches

Question> Is there a way that I can fix this GCC warning?

q0987
  • 34,938
  • 69
  • 242
  • 387
  • 1
    Two structures with the same internals, differing only by case? What? I'm on GCC's side here. This is weird. – tadman Jun 08 '23 at 19:18
  • I have two structs which has same structures at this moment but with different names. Here I just show a simplified example. – q0987 Jun 08 '23 at 19:19
  • 1
    You can think the struct as file_format_a_header and file_format_b_header. I have updated the OP and change the struct names. – q0987 Jun 08 '23 at 19:20
  • 1
    The error still comes up if `int i;` is changed to `float x;` in one of the structs. It seems the error is based on the values being computed at compile time. – dbush Jun 08 '23 at 19:27
  • 1
    @dbush, To me, this looks like a gcc bug. – q0987 Jun 08 '23 at 19:29
  • Turn down the warnings? You asked for them, and it told you. – Weather Vane Jun 08 '23 at 19:29
  • 1
    @WeatherVane, I cannot turn down the warnings which are set by the firm. – q0987 Jun 08 '23 at 19:29
  • Then the solution is not to write such code. – Weather Vane Jun 08 '23 at 19:29
  • You can add some pragmas to suppress them locally. You have some code that is "almost intentionally" violating fixed rules. So it is logical to suppress these rules in this case if this code is an exception. – Eugene Sh. Jun 08 '23 at 19:29
  • @WeatherVane, I could just use "len = sizeof(struct file_format_a_header )" without checking. But this can easily introduce bugs later if someone updates either of the struct. – q0987 Jun 08 '23 at 19:31
  • [Use #pragma to disable the warning in those lines.](https://stackoverflow.com/questions/3378560/how-to-disable-gcc-warnings-for-a-few-lines-of-code) – Eric Postpischil Jun 08 '23 at 19:32
  • @q0987 if the firm has set the warning policy, are you allowed to disable it? – Weather Vane Jun 08 '23 at 19:34
  • Does using a ternary operator fix the problem? – user16217248 Jun 08 '23 at 19:47
  • @user16217248 Nope, it still catches it. – dbush Jun 08 '23 at 19:49

1 Answers1

3

gcc is likely generating a warning here because the result of the sizeof operator is a compile time constant (unless its operand is a variable length array).

So effectively it sees this:

    if (1 == type)
    {
        len = 4;
    }
    else
    {
        len = 4;
    }

This is happening even if the two structs in question have differently named members, differing member types, or a differing number of members, as long as the sizes are the same.

You can work around this by adding pragma to ignore this specific warning in a particular scope:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wduplicated-branches"
    if (1 == type)
    {
        len = sizeof(struct ABC);
    }
    else
    {
        len = sizeof(struct abc);
    }
#pragma GCC diagnostic pop
dbush
  • 205,898
  • 23
  • 218
  • 273
  • This does fix the issue. However, I still don't understand why GCC reports this as WARNING in the first place. – q0987 Jun 08 '23 at 19:38
  • 2
    @q0987 Because `sizeof` is evaluated at compile time. So both lines `len =....` generate the same code in two different branches. And your command line is explicitly asking the compiler to warn about these things. – Eugene Sh. Jun 08 '23 at 19:47
  • @EugeneSh.: That is overly simplistic. GCC is also evaluating the warning at compile time. It can see the two branches are not semantically identical (one uses the size of one structure, the other uses the size of another structure), and this is reasonable code—the user wants one size or another, and they could differ if the structures were different (e.g., if the structure definitions were controlled by preprocessor options that included/excluded different members), and the user should not be expected to calculate structure sizes and write code for when they are the same… – Eric Postpischil Jun 08 '23 at 20:45
  • … How would they even do that? They could not test `sizeof(struct ABC) == sizeof(struct abc)` in the preprocessor. There is an argument the compiler should be smarter here. – Eric Postpischil Jun 08 '23 at 20:45