1

Code :

#include <stdio.h>

typedef struct{
  int i;
  int tab[];
}mystr;

mystr a = {1,{0,1,2}};

int main(void){
  printf("%d%d%d\n",a.i,a.tab[0],a.tab[1]);
  return 0;
}

C compiling :

$ gcc main.c -o main && ./main
101

C++ compiling :

$ g++ main.c -o main && ./main
main.c:8:27: error: too many initializers for ‘int [0]’
 const mystr a = {1,{0,1,2}};
                           ^

I do understand the problem, it is that tab have no any memory allocated. But why this is ok for C ? Why do C++ doesn't automatically allocate the memory space for the tab ? I Know that structures are similar to objects in C++ but may be there is some subtleties that I do not know about global object instantiation ?

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
Welgriv
  • 714
  • 9
  • 24
  • 7
    c++ doesn't allow 0 sized c arrays or c arrays of unknown sizes. Possible duplicate : https://stackoverflow.com/questions/9722632/what-happens-if-i-define-a-0-size-array-in-c-c – François Andrieux Nov 21 '18 at 16:21
  • 7
    You will do yourself a favor if you think of C and C++ as two completely separate languages that just happen to share a lot of the same keywords. – NathanOliver Nov 21 '18 at 16:22
  • 1
    The code is invalid in C and C++. You need to pay attention to diagnostic messages issued by C compiler as well. – AnT stands with Russia Nov 21 '18 at 16:22
  • @FrançoisAndrieux but C does ? – Welgriv Nov 21 '18 at 16:22
  • 3
    C and C++ are different languages, so why expect them to behave the same way? – Chris Turner Nov 21 '18 at 16:22
  • @Welgriv I don't know if it does. I'm choosing not to assume the rules of c based on my knowledge of c++. Don't take my not mentioning the rules of c as implying that it's allowed. Edit : I see now from the wording of the question how my comment could have been seen as stating a difference between c++ and c rather than just stating a fact about c++. Sorry for the confusion. – François Andrieux Nov 21 '18 at 16:23
  • @AnT Ok so my `gcc` is wrong ? > – Welgriv Nov 21 '18 at 16:23
  • @Welgriv didn't you just ignore conformance warnings of your compiler? – Öö Tiib Nov 21 '18 at 16:32
  • Welgriv, they put you through the ringer on this one, but it's actuallly a good question, and you included all the information we needed to see taht when invoked with default settings, `gcc` does indeed compile this without further errors. @ÖöTiib, did you actually bother trying it ? – erik258 Nov 21 '18 at 16:33
  • @Welgriv: It is often wrong. But not in this case. Just rememberr that GCC often by default reports many serious language "errors" as "warnings". You simply ignored its complaints. Specifying `-std=...` and `-pedantic-errors` in command line might help you to pay more attention to such errors. – AnT stands with Russia Nov 21 '18 at 16:33
  • @DanFarrell gcc gives conformance warnings with -pedantic not by default since by default it compiles some sort of "gnuC" language not C. – Öö Tiib Nov 21 '18 at 16:38
  • https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html for a description of the extension. – Marc Glisse Nov 21 '18 at 20:29

2 Answers2

7

The code is invalid in C. This is not allowed in C

typedef struct{
  int i;
  int tab[];
}mystr;

mystr a = {1,{0,1,2}};

Whatever behavior you observe in C mode is a quirk of your compiler that has nothing to do with the language. The compiler supports the code as a non-standard feature, an extension.

Your code is also invalid in C++, but for a reason that is completely different from what was reported by your compiler. In C++ you are not allowed to have [] arrays as class members at all. The compiler lets it slip through (as an extension again), but fails in another spot later.

So, the answer to your question would be: the compiler you are using has different quirks/extensions in C mode than in C++ mode. Which is not surprising, since these are very different languages.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 1
    So why did it compile and execute correctly with my gcc ? – Welgriv Nov 21 '18 at 16:24
  • @Welgriv Did you pay attention to warnings (and enabled them)? – Osiris Nov 21 '18 at 16:26
  • @Welgriv: No, it didn't! The word "compile" in C world has very specific meaning: it means "passed the compilation process without any language-mandated diagnostic messages". This code does not compile in GCC: see for yourself http://coliru.stacked-crooked.com/a/63b110261be01aa3 The warning you see is exactly that: a language-mandated diagnostic message indicating a constraint violation (an error) in your code. What happened next (whether it executed or not) does not matter at all. Your code is not valid C. – AnT stands with Russia Nov 21 '18 at 16:26
  • @Welgriv When compiling such code I get `warning: flexible array initialization is a GNU extension`, which means, that it is not part of C language, but is enabled by a compiler extension. – Algirdas Preidžius Nov 21 '18 at 16:27
  • @Welgriv Try disabling GNU language extensions by passing the `-std=` option with something that does not enable gnu stuff. Like `-std=c11`. And crank up the warnings. Also; the fact that something *compiles* means nothing more than that it is syntactically valid. It says *nothing* about whether it is *correct*. "It compiles" is a *very low* bar. – Jesper Juhl Nov 21 '18 at 16:29
  • 1
    If you are not good with observing compiler diagnostics and telling which messages are actually "errors", get a habit of running GCC with `-std=... -pedantic-errors` flags. – AnT stands with Russia Nov 21 '18 at 16:30
  • @AlgirdasPreidžius silently changing the compiler flags in your example and then telling the OP _thier_ command didn't compile without warning is frustratingly deceptive. Why not just say the truthful thing - that gcc will compile invalid code if not told to be pedantic about things! – erik258 Nov 21 '18 at 16:42
  • @DanFarrell But, that what pedantic means: To be pedantic about adhering to the standard, without using any compiler extensions, that accepts non-standard code. Which is what I already said in my original comment (in slightly different words). So, I fail to see the deception (Especially, since "deception" means "_the act of causing someone to accept as true or valid what is false or invalid_" ([source](https://www.merriam-webster.com/dictionary/deception)), what, about my original comment was false, or invalid?) – Algirdas Preidžius Nov 21 '18 at 17:42
  • @AlgirdasPreidžius, because you said "No, it didn't" when it fact it _did_ compile and run successfully exactly as the OP showed. – erik258 Nov 21 '18 at 17:53
  • 1
    @Dan Farrell: It's, again, a confusion created by different interpretations of the term *compile*. Some people believe that if the compiler created an executable, then the code "compiled and ran successfully", where "success" is based on their naive expectations (as opposed to language spec). That's a rather useless understanding of the term for C/C++ purposes. A more mature and meaningful interpretation of the term is, again: "code compiled" = "code passed the compilation process without any language-mandated diagnostic messages". In this case the code did not really compile. – AnT stands with Russia Nov 21 '18 at 18:03
1

Everything in the upvoted answer might be accurate, but it dances around the root of your question. You're absolutely right - on debian and alpine docker images, and a gcc invocation that doesn't include -pedantic does compile this and run it without complaint:

root@45c9da7956c8:/# cat t.c; gcc -std=c11 -o t t.c && ./t;
#include <stdio.h>

typedef struct{
  int i;
  int tab[];
}mystr;

mystr a = {1,{0,1,2}};

int main(void){
  printf("%d%d%d\n",a.i,a.tab[0],a.tab[1]);
  return 0;
}
101

Gcc is a very accomodating compiler, and will work with things that can only be described accurately as out of spec. That doesn't necessarily make it a bad compiler - but it does make it a poor test of whether code is standards compliant. -pedantic will help with that.

I'll echo the point made in the question comments that it really is conceptually best to think of C and C++ as completely different languages. At least, I can't think of a case where getting C code to compile on a c++ compiler would have any value. Thinking of them as completely separate is a valid model for how they act in real life.

erik258
  • 14,701
  • 2
  • 25
  • 31
  • 1
    Additionally, if one wants `gcc` to be of more help in identifying nonstandardisms, then turning off GNU extensions via the `-std=` option (e.g. `-std=c11`) is in order. Even then, however, the compiler does not promise to diagnose *all* standard conformance issues. – John Bollinger Nov 21 '18 at 16:47