[cfe-dev] Handling of empty structs in C

Reid Kleckner rnk at google.com
Tue Nov 5 10:19:03 PST 2013


IMO extern "C" is a clear indication that the user wants to interoperate
between C and C++.  clang should have this warning on by default in extern
"C" contexts.

On Tue, Nov 5, 2013 at 8:56 AM, Serge Pavlov <sepavloff at gmail.com> wrote:

> When combining C and C++ files it is recommended to specify option
> '-Wc++-compat. It enables specific messages related to incompatibilities
> between C and C++. In your example relevant message appears:
>
> clang -Wc++-compat -c lib.c -o lib.o
> In file included from lib.c:1:
> ./header.h:5:9: warning: empty struct has size 0 in C, size 1 in C++
> [-Wc++-compat]
> typedef struct empty { } empty;
>
> But -Wall doesn't enable these warnings.
>
> Thanks,
> --Serge
>         ^
> 1 warning generated.
>
>
> 2013/11/5 Andy Gibbs <andyg1001 at hotmail.co.uk>
>
>> Hi,
>>
>> I have just helped a colleague track down a bug in a project using mixed
>> C and C++ code which revolved around the fact that an empty struct in C has
>> zero size and in C++ has non-zero size.  Since a picture is a thousand
>> words, a simplified version of the code is as follows:
>>
>>
>> header.h
>> ========
>> #ifdef __cplusplus
>> extern "C" {
>> #endif
>>
>> typedef struct empty { } empty;
>>
>> typedef struct test {
>>  empty a;
>>  char b;
>> } test;
>>
>> void set(test* p);
>>
>> #ifdef __cplusplus
>> }
>> #endif
>>
>>
>> lib.c
>> =====
>> #include "header.h"
>>
>> void set(test* p) {
>>  p->b = 10;
>> }
>>
>>
>> main.cpp
>> ========
>> #include <stdio.h>
>> #include "header.h"
>>
>> int main() {
>>  test t;
>>  t.b = 0;
>>  set(&t);
>>  printf("%i\n", t.b);
>>  return 0;
>> }
>>
>>
>> compile.sh
>> ==========
>> #!/bin/bash
>>
>> clang -Wall -c lib.c -o lib.o &&
>> clang -Wall -c main.cpp -o main.o &&
>> clang main.o lib.o -o test
>>
>>
>> So, the program outputs "0", not "10", and once I'd looked twice (*cough*
>> at least!), the problem was quite apparent, although somewhat obfuscated by
>> the fact that the empty struct was buried deep inside library headers and
>> only became empty due some arcane macro logic...
>>
>> Long story short, I'm ok with the fact that C and C++ handle empty
>> structs differently, but I was somewhat challenged by my colleague's
>> complaint that surely the compiler should have given a warning that the
>> structure of 'struct test' varies depending on the language it is used
>> from, especially given that the include file uses 'extern "C"' implying a
>> library originating in C that can be used from C++ code.
>>
>> I know that '-pedantic' throws up a warning about a GNU extension, but my
>> suggestion would be that there be a specific warning such as "struct
>> differs in size in C and C++ modes" when parsing an empty struct or a
>> struct containing an empty struct inside an 'extern "C"' block.
>>
>> Good idea?  Bad idea?  I'm happy to work on a patch to clang if people
>> think this has merit.
>>
>> Cheers,
>>
>> Andy
>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>
>
>
> --
> Thanks,
> --Serge
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131105/086fdb3c/attachment.html>


More information about the cfe-dev mailing list