1

I was told this is true (in the pearson book How to Program), however when compiling inside the ide of NetBeans,

the following function code

int n[5] = {6, 5, 4, 3, 2, 1, 2, 3, 2};

does not result in a compile time error however does cause unexpected behavior further in the program. Accessing locations in the array that shouldn't exist also does not cause a syntax error.

printf("%d", n[7]);

Am I missing something?

  • 4
    Not a syntax error, but worse: undefined behaviour... – cs95 Sep 11 '17 at 00:18
  • A syntax error is clearly a violation of syntax rules, this is not such. Instead as @cᴏʟᴅsᴘᴇᴇᴅ commented, it would cause *undefined behavior*. – Iharob Al Asimi Sep 11 '17 at 00:28
  • 5
    It is a constraint violation and must be reported by the compiler. It isn't really a syntax error though. It is syntactically correct but semantically incorrect. – Jonathan Leffler Sep 11 '17 at 00:33
  • 3
    @cᴏʟᴅsᴘᴇᴇᴅ — it isn't UB. It is defined to be incorrect. – Jonathan Leffler Sep 11 '17 at 00:37
  • We had this question dozens of times already, One just recently: https://stackoverflow.com/questions/46144353/how-does-below-method-of-array-intialization-differ-in-context-to-array-bounds-c Get a better C book and drop obscure youtube videos and blogs. – too honest for this site Sep 11 '17 at 00:47
  • @JonathanLeffler: Accessing an array beyond bounds **is** UB. – too honest for this site Sep 11 '17 at 00:50
  • @Olaf — the initialization prevents the code from compiling. The out of bounds access at runtime is UB once you get the code compiling. I was referring to the first problem not being UB. The second problem is UB, but only once the first is fixed and only if the array isn't big enough. – Jonathan Leffler Sep 11 '17 at 00:54
  • @JonathanLeffler: We don't know what coldspeed refers to. Benefit of doubt and so… Anyway, this is a dupe of https://stackoverflow.com/questions/46144353/how-does-below-method-of-array-intialization-differ-in-context-to-array-bounds-c some hours ago. Coincidence? … Nah … – too honest for this site Sep 11 '17 at 00:56
  • Netbeans is an IDE, nota compiler. Which compiler do you use? Any compliant has to emit a diagnostic message. gcc for instance does - with default warning settings. – too honest for this site Sep 11 '17 at 01:02
  • 1
    MSVC reports *error C2078: too many initializers* (not a "syntax" error). – Weather Vane Sep 11 '17 at 01:10
  • It would be interesting to know which compiler you are using so we can publically shame it on the internet. It might be misconfigured to not compile for standard C. – Lundin Sep 11 '17 at 09:38

2 Answers2

4

Yes this code is wrong:

int n[5] = {6, 5, 4, 3, 2, 1, 2, 3, 2};

Per 6.7.9 Initialization, paragraph 2 of the C standard:

Constraints

No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

As noted in the comments, this is a constraint violation and a semantic error that must be reported by the compiler. I'd say any compiler that fails to report this error is deficient.

Community
  • 1
  • 1
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • I understand that it is wrong, however the pearson book how to program just told me that it was a syntax Error so thats what I was looking to check with. – Adam Goodsell Sep 11 '17 at 00:28
  • It's not a syntax error, how can it be? The compiler knows that there are more elements ... blah blah blah, but *syntactically*, it's a valid expresion. – Iharob Al Asimi Sep 11 '17 at 00:29
  • @IharobAlAsimi I quoted the C standard, which **clearly** and **specifically** states "No initializer shall attempt to provide a value for an object not contained within the entity being initialized." The C standard seems to be silent as to exactly what type of error it is, but how can you claim it's NOT a syntax error given that paragraph? – Andrew Henle Sep 11 '17 at 00:30
  • @AndrewHenle That is from $ **6.7.9 Initialization**, nothing to do with syntax rules. It can be an error, but I doubt it's a *syntax* error. – Iharob Al Asimi Sep 11 '17 at 00:32
  • @IharobAlAsimi OK, then *what* kind of rule is it? As noted in another answer, GCC enforces the standard with an actual error. I suspect GCC authors are quite familiar with applying the C standard to building an actual C compiler. – Andrew Henle Sep 11 '17 at 00:33
  • @IharobAlAsimi The compiler considers syntactical errors and semantic errors in general as compiler errors. – Vlad from Moscow Sep 11 '17 at 00:35
  • @AdamGoodsell: Looks like you should get a better book then. Or you missinterpreted something. – too honest for this site Sep 11 '17 at 01:06
  • @VladfromMoscow *compilation error* != *syntax error*, that's what I am trying to say. – Iharob Al Asimi Sep 11 '17 at 14:37
1

Yes, it is a constraint violation (aka "error") in C. Calling it a "syntax error" would be incorrect though. There's nothing wrong with the syntax in your declaration.

The only exception from this rule is permission to let the trailing zero-terminator to "fall off" the end of the character array when the initializer is expressed by a string literal

char str[5] = "Hello";

The above is valid in C even though the terminating \0 character does fit into the array. (The \0 character is discarded when it does not fit.)

If your compiler issued a warning for your declaration, then by issuing a warning it formally complied with standard requirements. Compilers like GCC will issue an error in -pedantic-errors mode.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • About `str` initialisation being valid. Could you tell me how it works? Is the array size automatically made `6` to accommodate the `\0`? I mean, otherwise the `\0` could be written to some other adjacent memory and cause problems. I did `char s[5]="hello";` and printed `sizeof(s)` - it was still `5`. – J...S Sep 11 '17 at 00:59
  • 1
    @J...S: No, in such cases the trailing `\0` is completely suppressed/ignored. The array keeps the declared size and nothing is written into the adjacent memory. – AnT stands with Russia Sep 11 '17 at 01:01
  • gcc emits a warning without extra options (it has to). – too honest for this site Sep 11 '17 at 01:03
  • So the string probably won't stop where we want it to when printed out because of the missing `\0`. Thanks! – J...S Sep 11 '17 at 01:05
  • 1
    @J...S - It isn't even a string when it is not properly terminated. But you are allowed to have an array of `char` just as well as having an array of `int`. Just don't try `strlen` or anything similar. – Bo Persson Sep 11 '17 at 12:28
  • @BoPersson It seems that in gcc and clang, the extra values are ignored for all types of array not just `char`. I tried `int arr[4]={1, 2, 3, 4, 5, 6}` and printed `arr[5]`. It ignored the value in the initializer list and had garbage value. – J...S Sep 11 '17 at 16:31
  • @J...S: That's how it should be. That's what expected from a compiler that decides to support this declaration as an extension. Anything else (i.e. either extending an array with explicitly specified size, or writing into memory beyond the array boundary) would look rather weird in the realm of C language. – AnT stands with Russia Sep 11 '17 at 16:49