string literal initializer

V

Vincenzo Mercuri

Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
I am a bit embarassed for the silliness of my question: :-}

Is
char s[4] = "aaaaaaaa";

a constraint violation?
I think it violates 6.7.8 p2 , and both gcc and dmc diagnose it.

But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?

Hi (ciao!),

N1256 draft 6.7.8 p2 states:

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

The word "shall" stays both for suggestion and
the Standard hopes you won't do that.

Let's try (gcc under cygwin):

main.c:

#include <stdio.h>

int main(void){

char s[4] = "aaaaaaaa";

for(int i = 0; i < 8; i++)
putchar( s );

return 0;

}

$gcc -std=c99 main.c
main.c: In function 'main':
main.c:5: warning: initalizer-string for array of chars is too long

$./a.exe
aaaa♦ @

So, althought it compiles you are warned about a defect.
That is a severe one.
This code is completely useless and there is no
reason to exceed the array bounds unless you want your program to
crash as soon as it increases in size (or even before),
have an unpredictable behaviour, including memory access errors,
or to make it very exploits prone.
 
L

Luca Forlizzi

I am a bit embarassed for the silliness of my question: :-}

Is
char s[4] = "aaaaaaaa";

a constraint violation?
I think it violates 6.7.8 p2 , and both gcc and dmc diagnose it.

But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?
 
R

Ralf Damaschke

Richard said:
Luca said:
But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?

Yes.

If -[cut]- meets the condition of 6.7.8p14 (I don't have access to
the book) they would be right (and then the mentioned difference to
C++ makes sense).

-- Ralf
 
V

Vincenzo Mercuri

Il 19/06/2010 22.10, bart.c ha scritto:
Vincenzo Mercuri said:
Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
char s[4] = "aaaaaaaa";

a constraint violation?
This code is completely useless and there is no
reason to exceed the array bounds unless you want your program to
crash as soon as it increases in size (or even before),
have an unpredictable behaviour, including memory access errors,
or to make it very exploits prone.

Not completely useless; you might have a set of strings which you want
the compiler to trim to N characters (say, the first N characters of a
set of commands).

Just making the strings shorter is no good: it means having to hard-code
N in the contents of the strings, and if someone later makes N bigger,
then the extra content no longer exists.

(It does require means to ensure the correct zero terminator in each
string; eg:

#define N 4

char firstnlettersofthealphabet[N+1]="abcdefghijklmnopqrstuvwxyz";

firstnlettersofthealphabet[N]=0;

printf("First %d letters of the alphabet are:
%s\n",N,firstnlettersofthealphabet);

Now it works for any N, without having to store all 26 letters.)

Actually you might be right.

"might" because it depends on the implementation.
For example, gcc under cygwin allows you to do that,
even though intel compiler doesnt (maybe it allows you to just exceed
the initialization of 1 character over the declared array size).
So I think it shouldn't be considered good style, if not risky or
completely wrong, I don't know. And not just for sake
of compilation in itself but even for a possible future reusability of
your code, and I should also mention the C++ compatibility.
I'd prefer to write a little loop running from the decimal value 97 to
122 of the ASCII set of characters, in order to get a subset of the
alphabet.
 
L

lawrence.jones

Luca Forlizzi said:
I am a bit embarassed for the silliness of my question: :-}

Is
char s[4] = "aaaaaaaa";

a constraint violation?
I think it violates 6.7.8 p2 , and both gcc and dmc diagnose it.

But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?

It depends on *exactly* what it says. It is not an error if the string
is exactly one character too long (i.e., it is allowable for the
terminating null character to not be used in the initialization), but it
is a constraint violation if the string is more than one character too
long.
 
B

bart.c

Vincenzo Mercuri said:
Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
char s[4] = "aaaaaaaa";

a constraint violation?
This code is completely useless and there is no
reason to exceed the array bounds unless you want your program to
crash as soon as it increases in size (or even before),
have an unpredictable behaviour, including memory access errors,
or to make it very exploits prone.

Not completely useless; you might have a set of strings which you want the
compiler to trim to N characters (say, the first N characters of a set of
commands).

Just making the strings shorter is no good: it means having to hard-code N
in the contents of the strings, and if someone later makes N bigger, then
the extra content no longer exists.

(It does require means to ensure the correct zero terminator in each string;
eg:

#define N 4

char firstnlettersofthealphabet[N+1]="abcdefghijklmnopqrstuvwxyz";

firstnlettersofthealphabet[N]=0;

printf("First %d letters of the alphabet are:
%s\n",N,firstnlettersofthealphabet);

Now it works for any N, without having to store all 26 letters.)
 
L

Luca Forlizzi

Richard said:
Luca said:
But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?

If -[cut]- meets the condition of 6.7.8p14 (I don't have access to
the book) they would be right (and then the mentioned difference to
C++ makes sense).

-- Ralf

no, the "cut" part is a comment like " althogh this is confusing for
the beginner".
I don't have the book here right now, but it does not change the
meaning.
 
A

Andrey Tarasevich

Luca said:
Is
char s[4] = "aaaaaaaa";

a constraint violation?
Yes.

I think it violates 6.7.8 p2 , and both gcc and dmc diagnose it.

They are right to diagnose it.
But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?

The book is _partially_ wrong. One difference between C and C++ is that
in C you are allowed to have the terminating null-character "fall off"
the end of the array. i.e.

char s[4] = "aaaa";

is legal in C, meaning that the terminating zero is simply ignored. In
C++ this initialization is ill-formed.

However, your original example is invalid in both C and C++.
 
K

Keith Thompson

Andrey Tarasevich said:
Luca said:
Is
char s[4] = "aaaaaaaa";

a constraint violation?
Yes.

I think it violates 6.7.8 p2 , and both gcc and dmc diagnose it.

They are right to diagnose it.
But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?

The book is _partially_ wrong. One difference between C and C++ is that
in C you are allowed to have the terminating null-character "fall off"
the end of the array. i.e.

char s[4] = "aaaa";

is legal in C, meaning that the terminating zero is simply ignored. In
C++ this initialization is ill-formed.

However, your original example is invalid in both C and C++.

Yes, it's an error in H&S 5, and it's not listed in the errata.

See <http://www.careferencemanual.com/>, under "Contact the Author", to
report it. I suggest that Luca, the person who found the error, should
report it (or if you like I can do so and give proper credit).
 
L

Luca Forlizzi

Andrey Tarasevich said:
Luca said:
Is
 char s[4] = "aaaaaaaa";
a constraint violation?
I think it violates 6.7.8 p2 , and both gcc and dmc diagnose it.
They are right to diagnose it.
But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?
The book is _partially_ wrong. One difference between C and C++ is that
in C you are allowed to have the terminating null-character "fall off"
the end of the array. i.e.
     char s[4] = "aaaa";
is legal in C, meaning that the terminating zero is simply ignored. In
C++ this initialization is ill-formed.
However, your original example is invalid in both C and C++.

Yes, it's an error in H&S 5, and it's not listed in the errata.

See <http://www.careferencemanual.com/>, under "Contact the Author", to
report it.  I suggest that Luca, the person who found the error, should
report it (or if you like I can do so and give proper credit).

I will take the task of contacting the authors.
Thanks for the suggestion!
 
V

Vincenzo Mercuri

Vincenzo said:
Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
I am a bit embarassed for the silliness of my question: :-}

Is
char s[4] = "aaaaaaaa";

a constraint violation?
I think it violates 6.7.8 p2 , and both gcc and dmc diagnose it.

But H&S 5th edition says "It is not an error - [cut] - if the string
is too long for a
character array of specified size. (It is an error in C++)."
Is the book wrong?

Hi (ciao!),

N1256 draft 6.7.8 p2 states:

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

The word "shall" stays both for suggestion and
the Standard hopes you won't do that.
what am I saying?
The Sandard clearly requires the value to fit the size of the object
being initialized. No doubts. If gcc compiles it is not
consistent with that requirement.
 
K

Keith Thompson

pete said:
Vincenzo said:
Vincenzo said:
Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
I am a bit embarassed for the silliness of my question: :-}

Is
char s[4] = "aaaaaaaa";
N1256 draft 6.7.8 p2 states:

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

The word "shall" stays both for suggestion and
the Standard hopes you won't do that.
If gcc compiles it is not
consistent with that requirement.

I disagree.

So do I, but probably not for the same reason.
N869

3.18
[#1] undefined behavior
[definition snipped]

I'm not quite sure what your intent was in quoting the definition
of "undefined behavior".

The quoted sentence from N1256 is in a constraint, so any conforming
implementation must issue a diagnostic if it's violated, as it is
in the quoted declaration. gcc does so (the diagnostic happens
to be a non-fatal warning, but that's fine as far as the standard
is concerned).

If the compiler chooses to compile the program in spite of the
constraint violation, the program's behavior is undefined.

I'd prefer that gcc treated this as an error, causing the compilation
to fail. There is no reasonable behavior for the declaration,
and gcc isn't doing the programmer any favors by allowing it
to compile. But that's a quality-of-implementation issue, not a
conformance issue.

Experiment shows that gcc treats
char s[4] = "aaaaaaaa";
as equivalent to
char s[4] = "aaaa";
 
V

Vincenzo Mercuri

Il 30/06/2010 23.21, Keith Thompson ha scritto:
pete said:
Vincenzo said:
Vincenzo Mercuri wrote:
Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
I am a bit embarassed for the silliness of my question: :-}

Is
char s[4] = "aaaaaaaa";
N1256 draft 6.7.8 p2 states:

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

The word "shall" stays both for suggestion and
the Standard hopes you won't do that.
If gcc compiles it is not
consistent with that requirement.

I disagree.

So do I, but probably not for the same reason.
N869

3.18
[#1] undefined behavior
[definition snipped]

I'm not quite sure what your intent was in quoting the definition
of "undefined behavior".

The quoted sentence from N1256 is in a constraint, so any conforming
implementation must issue a diagnostic if it's violated,

What are the parts of the Standard that require
implementations to issue at least a diagnostic and what
those that requires an 'error' to be issued?
I am asking because it is my intention to read carefully
the Standard from the beginning but I want be sure to 'interpret',
or better, to 'understand' it, the right way.
 
L

Luca Forlizzi

Il 30/06/2010 23.21, Keith Thompson ha scritto:


pete said:
Vincenzo Mercuri wrote:
Vincenzo Mercuri wrote:
Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
I am a bit embarassed for the silliness of my question: :-}
Is
char s[4] = "aaaaaaaa";
N1256 draft 6.7.8 p2 states:
"No initializer shall attempt to provide a value for an object
not contained within the entity being initialized"
The word "shall" stays both for suggestion and
the Standard hopes you won't do that.
If gcc compiles it is not
consistent with that requirement.
I disagree.
So do I, but probably not for the same reason.
N869
        3.18
        [#1] undefined behavior
[definition snipped]
I'm not quite sure what your intent was in quoting the definition
of "undefined behavior".
The quoted sentence from N1256 is in a constraint, so any conforming
implementation must issue a diagnostic if it's violated,

What are the parts of the Standard that require
implementations to issue at least a diagnostic and what
those that requires an 'error' to be issued?
I am asking because it is my intention to read carefully
the Standard from the beginning but I want be sure to 'interpret',
or better, to 'understand' it, the right way.

AFAIK there is no notion of "error" in the standard.
when detecting a constraint violation, an implementation is only
required to issue a diagnostic. That's all.
In this case gcc decide to compile anyway, after printing the
diagnostics, the Standard allows it.
 
V

Vincenzo Mercuri

Luca Forlizzi ha scritto:
Il 30/06/2010 23.21, Keith Thompson ha scritto:


Vincenzo Mercuri wrote:
Vincenzo Mercuri wrote:
Il 19/06/2010 20.17, Luca Forlizzi ha scritto:
I am a bit embarassed for the silliness of my question: :-}
Is
char s[4] = "aaaaaaaa";
N1256 draft 6.7.8 p2 states:
"No initializer shall attempt to provide a value for an object
not contained within the entity being initialized"
The word "shall" stays both for suggestion and
the Standard hopes you won't do that.
If gcc compiles it is not
consistent with that requirement.
I disagree.
So do I, but probably not for the same reason.

3.18
[#1] undefined behavior
[definition snipped]
I'm not quite sure what your intent was in quoting the definition
of "undefined behavior".
The quoted sentence from N1256 is in a constraint, so any conforming
implementation must issue a diagnostic if it's violated,

What are the parts of the Standard that require
implementations to issue at least a diagnostic and what
those that requires an 'error' to be issued?
I am asking because it is my intention to read carefully
the Standard from the beginning but I want be sure to 'interpret',
or better, to 'understand' it, the right way.

AFAIK there is no notion of "error" in the standard.
when detecting a constraint violation, an implementation is only
required to issue a diagnostic. That's all.
In this case gcc decide to compile anyway, after printing the
diagnostics, the Standard allows it.

Thanks
 
L

Luca Forlizzi

There is some slight notion of "error" in the standard.

ISO/IEC 9899:1999 (E)
4. Conformance
4 The implementation shall not successfully translate
  a preprocessing translation unit containing
  a #error preprocessing directive
  unless it is part of a group skipped by conditional inclusion.

ah, right, I forgot about it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top