By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,993 Members | 1,947 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,993 IT Pros & Developers. It's quick & easy.

Best way of clearing a compiler warning?

P: n/a

Hello,

Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
return(-2);
}

With the above code, the compiler (gcc) gives the following warning:

digest.c:121: warning: passing arg 1 of `error' discards qualifiers from
pointer target type.

The function error is declared as follows:

void error(char *errmsg, int code);

Why does it give this message and how do I silence it?

Thanks

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep

Nov 15 '05 #1
Share this Question
Share on Google+
29 Replies


P: n/a
Daniel Rudy wrote:
Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
return(-2);
}

With the above code, the compiler (gcc) gives the following warning:

digest.c:121: warning: passing arg 1 of `error' discards qualifiers from
pointer target type.

The function error is declared as follows:

void error(char *errmsg, int code);

Why does it give this message
Because you're passing a string literal, which is const. `error' is
declared as taking a char*, meaning it does not promise not to modify
the contents of its argument. If it does, Bad Things will happen.
and how do I silence it?

If `error' really doesn't modify `errmsg', change the prototype and the
function to take a const char* instead.

If it does modify `errmsg', you'll have to copy the message to a newly
allocated string.

S.
Nov 15 '05 #2

P: n/a
At about the time of 11/6/2005 4:59 PM, Skarmander stated the following:
Daniel Rudy wrote:
Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
return(-2);
}

With the above code, the compiler (gcc) gives the following warning:

digest.c:121: warning: passing arg 1 of `error' discards qualifiers from
pointer target type.

The function error is declared as follows:

void error(char *errmsg, int code);

Why does it give this message

Because you're passing a string literal, which is const. `error' is
declared as taking a char*, meaning it does not promise not to modify
the contents of its argument. If it does, Bad Things will happen.


I see. error does not modify the contents of *errmsg, just prints it
out using either syslog or fprintf to stderr.
and how do I silence it?


If `error' really doesn't modify `errmsg', change the prototype and the
function to take a const char* instead.

If it does modify `errmsg', you'll have to copy the message to a newly
allocated string.

S.


Ah, thanks.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Nov 15 '05 #3

P: n/a
Skarmander wrote:

Daniel Rudy wrote:
Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
return(-2);
}

With the above code, the compiler (gcc) gives the following warning:

digest.c:121:
warning: passing arg 1 of `error' discards qualifiers from
pointer target type.

The function error is declared as follows:

void error(char *errmsg, int code);

Why does it give this message


Because you're passing a string literal, which is const.


A string literal isn't const qualified.

--
pete
Nov 15 '05 #4

P: n/a
At about the time of 11/6/2005 5:08 PM, pete stated the following:
Skarmander wrote:
Daniel Rudy wrote:
Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
return(-2);
}

With the above code, the compiler (gcc) gives the following warning:

digest.c:121:
warning: passing arg 1 of `error' discards qualifiers from
pointer target type.

The function error is declared as follows:

void error(char *errmsg, int code);

Why does it give this message


Because you're passing a string literal, which is const.

A string literal isn't const qualified.


Even so, it seems to have corrected the problem. I don't get the
warning anymore.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Nov 15 '05 #5

P: n/a
Skarmander <in*****@dontmailme.com> writes:
Because you're passing a string literal, which is const.
No, you're wrong. String literals are not const in C. Here is a
quote from C99 section 6.4.5 "String Literals":

The multibyte character sequence is then used to initialize
an array of static storage duration and length just
sufficient to contain the sequence. For character string
literals, the array elements have type char, and are
initialized with the individual bytes of the multibyte
character sequence; [...]
`error' is declared as taking a char*, meaning it does not
promise not to modify the contents of its argument. If it does,
Bad Things will happen.


String literals are definitely unmodifiable. Continuing the
quote:

If the program attempts to modify such an array, the
behavior is undefined.

It is more likely that the OP is using the GCC option described
in the following quote from GCC's manual:

`-Wwrite-strings'
When compiling C, give string constants the type `const
char[LENGTH]' so that copying the address of one into a
non-`const' `char *' pointer will get a warning; when compiling
C++, warn about the deprecated conversion from string constants to
`char *'. These warnings will help you find at compile time code
that can try to write into a string constant, but only if you have
been very careful about using `const' in declarations and
prototypes. Otherwise, it will just be a nuisance; this is why we
did not make `-Wall' request these warnings.

GCC is not a C compiler when -Wwrite-strings is used. Instead,
it compiles a similar languages where string literals have type
const char[]. (It is very deceptive to make a -W warning option
change the language compiled.)
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 15 '05 #6

P: n/a
Daniel Rudy wrote:
At about the time of 11/6/2005 5:08 PM, pete stated the following:

Skarmander wrote:

Daniel Rudy wrote:
Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
return(-2);
}

With the above code, the compiler (gcc) gives the following warning:

digest.c:121:
warning: passing arg 1 of `error' discards qualifiers from
pointer target type.

The function error is declared as follows:

void error(char *errmsg, int code);

Why does it give this message

Because you're passing a string literal, which is const.

A string literal isn't const qualified.

Even so, it seems to have corrected the problem. I don't get the
warning anymore.


Yes. I gave you the right answer for the wrong reason.

S.
Nov 15 '05 #7

P: n/a
Daniel Rudy <sp******@spamthis.net> writes:
Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
return(-2);
}

With the above code, the compiler (gcc) gives the following warning:

digest.c:121: warning: passing arg 1 of `error' discards qualifiers from
pointer target type.

The function error is declared as follows:

void error(char *errmsg, int code);

Why does it give this message and how do I silence it?


The message implies that gcc thinks the argument is of type "const
char*". In fact, C string literals are of type "array of char"
(decaying to char*); modifying an element of a string literal doesn't
violate "const", but it does invoke undefined behavior.

gcc has an option to warn about attempts to modify string literals,
but it's implemented by pretending that string literals are const,
which would trigger the warning you're seeing. (Also, string literals
are const in C++; are you sure you're invoking gcc as a C compiler?)

One fix would be to cast the argument to char*:

error((char*)"digest.c: digest_file: Open File ", errno);

A better fix would be to modify the declaration of error() to:

void error(const char *errmsg, int code);

Presumably error() doesn't need to modify its argument anyway, so this
is a better description of what it does.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #8

P: n/a
Ben Pfaff wrote:
Skarmander <in*****@dontmailme.com> writes:

Because you're passing a string literal, which is const.

No, you're wrong. String literals are not const in C. Here is a
quote from C99 section 6.4.5 "String Literals":

<snip>

My bad. Is anyone surprised that they are const in C++, and that I've
gotten rather used to this?

And, of course, you're supposed to act as *if* they're const in C, or
undefined behavior will be your punishment. For hysterical reasons, etc.

S.
Nov 15 '05 #9

P: n/a
Ben Pfaff <bl*@cs.stanford.edu> writes:
[...]
It is more likely that the OP is using the GCC option described
in the following quote from GCC's manual:

`-Wwrite-strings'
When compiling C, give string constants the type `const
char[LENGTH]' so that copying the address of one into a
non-`const' `char *' pointer will get a warning; when compiling
C++, warn about the deprecated conversion from string constants to
`char *'. These warnings will help you find at compile time code
that can try to write into a string constant, but only if you have
been very careful about using `const' in declarations and
prototypes. Otherwise, it will just be a nuisance; this is why we
did not make `-Wall' request these warnings.

GCC is not a C compiler when -Wwrite-strings is used. Instead,
it compiles a similar languages where string literals have type
const char[]. (It is very deceptive to make a -W warning option
change the language compiled.)


The "-Wwrite-strings" option causes gcc to emit warnings when it
otherwise wouldn't. Since an implementation is allowed to issue
whatever spurious diagnostics it likes, that doesn't necessarily make
it non-conforming.

It would be better if the option did what its name implies -- i.e.,
cause gcc to issue warnings for attempts to modify string literals
without changing their type. Making them const is a quick and dirty
way to accomplish this; it has the unfortunate side effect of
producing *inaccurate* warnings, but the standard doesn't actually
require warnings to be accurate.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #10

P: n/a
Ben Pfaff wrote:
<snip>
`-Wwrite-strings'
When compiling C, give string constants the type `const
char[LENGTH]' so that copying the address of one into a
non-`const' `char *' pointer will get a warning; when compiling
C++, warn about the deprecated conversion from string constants to
`char *'. These warnings will help you find at compile time code
that can try to write into a string constant, but only if you have
been very careful about using `const' in declarations and
prototypes. Otherwise, it will just be a nuisance; this is why we
did not make `-Wall' request these warnings.

GCC is not a C compiler when -Wwrite-strings is used. Instead,
it compiles a similar languages where string literals have type
const char[]. (It is very deceptive to make a -W warning option
change the language compiled.)


gcc is still a C compiler with -Wwrite-strings, since the resulting code
is semantically equivalent to code where string literals are not
const, including undefined behavior for modifying literals. "An
implementation is free to produce any number of diagnostics as long as a
valid program is still correctly translated." This will be the case even
if -Wwrite-strings is used; the compiler is just generating diagnostics
when the standard doesn't require it to.

If gcc miscompiled (or refused to compile) valid code with
-Wwrite-strings, it would be another matter, but I don't think that can
happen. At worst you get extra diagnostics.

S.
Nov 15 '05 #11

P: n/a
At about the time of 11/6/2005 5:11 PM, Ben Pfaff stated the following:
Skarmander <in*****@dontmailme.com> writes:

Because you're passing a string literal, which is const.

No, you're wrong. String literals are not const in C. Here is a
quote from C99 section 6.4.5 "String Literals":

The multibyte character sequence is then used to initialize
an array of static storage duration and length just
sufficient to contain the sequence. For character string
literals, the array elements have type char, and are
initialized with the individual bytes of the multibyte
character sequence; [...]

`error' is declared as taking a char*, meaning it does not
promise not to modify the contents of its argument. If it does,
Bad Things will happen.


I don't _intentionally_ try to modify string literals or constants for
that matter in my programs. Accedentially now, may be another story...

String literals are definitely unmodifiable. Continuing the
quote:

If the program attempts to modify such an array, the
behavior is undefined.
Which is pretty much the same thing with a const.
It is more likely that the OP is using the GCC option described
in the following quote from GCC's manual:

`-Wwrite-strings'
When compiling C, give string constants the type `const
char[LENGTH]' so that copying the address of one into a
non-`const' `char *' pointer will get a warning; when compiling
C++, warn about the deprecated conversion from string constants to
`char *'. These warnings will help you find at compile time code
that can try to write into a string constant, but only if you have
been very careful about using `const' in declarations and
prototypes. Otherwise, it will just be a nuisance; this is why we
did not make `-Wall' request these warnings.

GCC is not a C compiler when -Wwrite-strings is used. Instead,
it compiles a similar languages where string literals have type
const char[]. (It is very deceptive to make a -W warning option
change the language compiled.)


Here's my command line:

gcc -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes
-Wmissing-prototypes -Wnested-externs -Wwrite-strings -Wfloat-equal
-Winline -Wtrigraphs -pedantic -ansi -std=c89 -ggdb3 -I.. -lm -lmd -lc
-lcrypto -o digest.test digest.test.c digest.c ../sha2.c ../error.c
.../syslog.c

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Nov 15 '05 #12

P: n/a
Daniel Rudy <sp******@spamthis.net> writes:
At about the time of 11/6/2005 5:11 PM, Ben Pfaff stated the following:
String literals are definitely unmodifiable. Continuing the
quote:

If the program attempts to modify such an array, the
behavior is undefined.
Which is pretty much the same thing with a const.


The effect of attempting to modify a string literal is the same
as attempting to modify a const object: both yield undefined
behavior. But a string literal is not actually const qualified.
It is more likely that the OP is using the GCC option described
in the following quote from GCC's manual:

`-Wwrite-strings'


[...]
Here's my command line:

gcc -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes
-Wmissing-prototypes -Wnested-externs -Wwrite-strings -Wfloat-equal ^^^^^^^^^^^^^^^
There you go. If you remove that, your original code should
compile free of that particular warning.
-Winline -Wtrigraphs -pedantic -ansi -std=c89 -ggdb3 -I.. -lm -lmd -lc
-lcrypto -o digest.test digest.test.c digest.c ../sha2.c ../error.c
../syslog.c


--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 15 '05 #13

P: n/a
Daniel Rudy wrote:
Hello,

Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);


Where is `error' declared? As far as I know, It's not in the standard
library.
August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
Nov 15 '05 #14

P: n/a
Ben Pfaff <bl*@cs.stanford.edu> writes:
Daniel Rudy <sp******@spamthis.net> writes:

[...]
Here's my command line:

gcc -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes
-Wmissing-prototypes -Wnested-externs -Wwrite-strings -Wfloat-equal

^^^^^^^^^^^^^^^
There you go. If you remove that, your original code should
compile free of that particular warning.
-Winline -Wtrigraphs -pedantic -ansi -std=c89 -ggdb3 -I.. -lm -lmd -lc
-lcrypto -o digest.test digest.test.c digest.c ../sha2.c ../error.c
../syslog.c


Yes, but it's a good warning.

Here's an inexact summary of the code in question:

void error(char *errmsg, int code);
....
error("This is an error message", errno);

Given this, the compiler can't tell whether error() modifies the
string passed to it. If it could analyze the actual implementation of
the error() function, it could safely refrain from warning about the
use of a string literal.

The best way to handle this is for the error() function to promise not
to modify the string that its argument points to; the compiler than
then warn about calls that might potentially violate that promise.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #15

P: n/a
In article <Hj*******************@newsb.telia.net>,
August Karlstrom <fu********@comhem.se> wrote:
fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);
Where is `error' declared?


In the bit of the message you snipped.

-- Richard
Nov 15 '05 #16

P: n/a
Skarmander <in*****@dontmailme.com> wrote:

And, of course, you're supposed to act as *if* they're const in C, or
undefined behavior will be your punishment. For hysterical reasons, etc.


You misspelled "hysterical raisins".

-Larry Jones

Let's just sit here a moment... and savor the impending terror. -- Calvin
Nov 15 '05 #17

P: n/a
At about the time of 11/6/2005 8:00 PM, August Karlstrom stated the
following:
Daniel Rudy wrote:
Hello,

Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);

Where is `error' declared? As far as I know, It's not in the standard
library.
August


Because it's not a standard function. It's one that I wrote to help
simplify error handling for my programs.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Nov 15 '05 #18

P: n/a
Daniel Rudy wrote:
At about the time of 11/6/2005 8:00 PM, August Karlstrom stated the
following:

Daniel Rudy wrote:

Hello,

Consider the following code fragment:

fileptr = fopen(param->filename, "r");
if (fileptr == NULL)
{
error("digest.c: digest_file: Open File ", errno);

Where is `error' declared? As far as I know, It's not in the standard
library.


Because it's not a standard function. It's one that I wrote to help
simplify error handling for my programs.


Yes, of course. When I reread your post it all makes sense. Sorry.
August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
Nov 15 '05 #19

P: n/a

In article <ln************@nuthaus.mib.org>, Keith Thompson <ks***@mib.org> writes:
Ben Pfaff <bl*@cs.stanford.edu> writes:

`-Wwrite-strings'
When compiling C, give string constants the type `const
char[LENGTH]' ...

GCC is not a C compiler when -Wwrite-strings is used. Instead,
it compiles a similar languages where string literals have type
const char[].
The "-Wwrite-strings" option causes gcc to emit warnings when it
otherwise wouldn't. Since an implementation is allowed to issue
whatever spurious diagnostics it likes, that doesn't necessarily make
it non-conforming.


No, but if the documentation is accurate, and -Wwrite-strings changes
the type of character literals, that *does* make it non-conforming.
It would be better if the option did what its name implies -- i.e.,
cause gcc to issue warnings for attempts to modify string literals
without changing their type.


Yes, as that would be conforming.

--
Michael Wojcik mi************@microfocus.com

Some there are, brave, high-souled fellows, who could borrow the world to
play at ball, and never feel the responsibility, whereas others are uneasy
and not themselves with a single shilling that does not belong to them.
-- Arthur Ransome
Nov 15 '05 #20

P: n/a

In article <43***********************@news.xs4all.nl>, Skarmander <in*****@dontmailme.com> writes:

gcc is still a C compiler with -Wwrite-strings, since the resulting code
is semantically equivalent to code where string literals are not
const, including undefined behavior for modifying literals.


And if that were the definition of a conforming implementation,
you'd be right. But it is not.

In a conforming implementation, character string literals have type
"array of char". Period. C99 6.4.5 does not allow any waffling
about semantic equivalence.

--
Michael Wojcik mi************@microfocus.com

The penance was not building the field and bringing back Shoeless Joe
Jackson, but rather tossing on the field with his father. -- Kevin Aug
Nov 15 '05 #21

P: n/a
mw*****@newsguy.com (Michael Wojcik) writes:
In article <43***********************@news.xs4all.nl>, Skarmander
<in*****@dontmailme.com> writes:
gcc is still a C compiler with -Wwrite-strings, since the resulting code
is semantically equivalent to code where string literals are not
const, including undefined behavior for modifying literals.


And if that were the definition of a conforming implementation,
you'd be right. But it is not.

In a conforming implementation, character string literals have type
"array of char". Period. C99 6.4.5 does not allow any waffling
about semantic equivalence.


At execution time, nothing really has a type; it's all zeros and ones.
An implementation is conforming if it behaves in a conforming manner.
If its documentation says that string literals are const, that doesn't
affect conformance, since the type of string literals isn't one of the
things an implementation is required to document.

As far as I know, gcc's treatment of string literals as const doesn't
affect the behavior of any strictly conforming program, cause any
strictly conforming program to fail to compile, or cause any required
diagnostic to fail to appear. (I'd be interested in seeing a
counterexample.) It does cause some non-required diagnostics to
appear, and some of those diagnostics are factually incorrect, but
that's not a conformance issue.

Of course, "-Wwrite-strings -Werror" does make gcc non-conforming;
"-Werror" causes warnings to be treated as errors.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #22

P: n/a
Michael Wojcik wrote:
In article <43***********************@news.xs4all.nl>, Skarmander <in*****@dontmailme.com> writes:
gcc is still a C compiler with -Wwrite-strings, since the resulting code
is semantically equivalent to code where string literals are not
const, including undefined behavior for modifying literals.

And if that were the definition of a conforming implementation,
you'd be right. But it is not.

In a conforming implementation, character string literals have type
"array of char". Period. C99 6.4.5 does not allow any waffling
about semantic equivalence.


So if gcc acts as a conforming implementation despite this option, gives
warnings when string literals are assigned to non-const pointers, and if
it had not described this effect in its documentation as assigning a
const type to literals, would that still be in violation?

This is getting to the point of a "tree falling in a forest with nobody
around to hear it" discussion, I admit. On one level, you are of course
right: the standard says to do A and gcc explicitly claims to do B,
which excludes A, hence it doesn't conform. But my (educated guess) is
that the difference can't be observed except through seeing additional
diagnostics, which the standard explicitly allows regardless of nature.

Whether you then feel justified calling gcc "(not) a C compiler" is a
question of how you line up your definitions, and how you define
conformance to an abstraction. It's not really a productive avenue of
discussion.

S.
Nov 15 '05 #23

P: n/a
On 2005-11-09, Skarmander <in*****@dontmailme.com> wrote:
Michael Wojcik wrote:
In article <43***********************@news.xs4all.nl>, Skarmander <in*****@dontmailme.com> writes:
gcc is still a C compiler with -Wwrite-strings, since the resulting code
is semantically equivalent to code where string literals are not
const, including undefined behavior for modifying literals.

And if that were the definition of a conforming implementation,
you'd be right. But it is not.

In a conforming implementation, character string literals have type
"array of char". Period. C99 6.4.5 does not allow any waffling
about semantic equivalence.


So if gcc acts as a conforming implementation despite this option, gives
warnings when string literals are assigned to non-const pointers, and if
it had not described this effect in its documentation as assigning a
const type to literals, would that still be in violation?

This is getting to the point of a "tree falling in a forest with nobody
around to hear it" discussion, I admit. On one level, you are of course
right: the standard says to do A and gcc explicitly claims to do B,
which excludes A, hence it doesn't conform. But my (educated guess) is
that the difference can't be observed except through seeing additional
diagnostics, which the standard explicitly allows regardless of nature.


I suppose the "as if" rule would have to apply here. It's acting "as if"
it is a conforming implementation with some spurious diagnostics. Now,
if the standard required that programs which attempt to assign to const
or otherwise violate const should fail to compile (AFAIK the standard is
not in the business of requiring things to fail to compile, only that
diagnostics must be printed), then gcc would be stuck between a rock and
a hard place, but still could get out of it by adding a "weak" const
which applies to only string literals - in which case, if a const falls
in a forest and no-one's around to read the diagnostic, did it really
happen?
Whether you then feel justified calling gcc "(not) a C compiler" is a
question of how you line up your definitions, and how you define
conformance to an abstraction. It's not really a productive avenue of
discussion.

S.

Nov 15 '05 #24

P: n/a
Keith Thompson wrote:
As far as I know, gcc's treatment of string literals as const doesn't
affect the behavior of any strictly conforming program, cause any
strictly conforming program to fail to compile, or cause any required
diagnostic to fail to appear.


Is there anything you can do with a string literal
in a C program, that you couldn't do if string
literals were const qualified by default?

I don't think so.

--
pete
Nov 15 '05 #25

P: n/a
At about the time of 11/6/2005 8:54 PM, Keith Thompson stated the following:
Ben Pfaff <bl*@cs.stanford.edu> writes:
Daniel Rudy <sp******@spamthis.net> writes:


[...]
Here's my command line:

gcc -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes
-Wmissing-prototypes -Wnested-externs -Wwrite-strings -Wfloat-equal


^^^^^^^^^^^^^^^
There you go. If you remove that, your original code should
compile free of that particular warning.

-Winline -Wtrigraphs -pedantic -ansi -std=c89 -ggdb3 -I.. -lm -lmd -lc
-lcrypto -o digest.test digest.test.c digest.c ../sha2.c ../error.c
../syslog.c

Yes, but it's a good warning.

Here's an inexact summary of the code in question:

void error(char *errmsg, int code);
...
error("This is an error message", errno);

Given this, the compiler can't tell whether error() modifies the
string passed to it. If it could analyze the actual implementation of
the error() function, it could safely refrain from warning about the
use of a string literal.

The best way to handle this is for the error() function to promise not
to modify the string that its argument points to; the compiler than
then warn about calls that might potentially violate that promise.


FWIW, the reason why I specify the warnings that I do is to force me
into writing clean, conforming, and correct code that will compile and
run on the widest number of systems out there with any problems. Right
now, my code will work on *BSD systems and possibly Linux as well, but
this is a platform issue, not a C issue.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Nov 15 '05 #26

P: n/a
pete <pf*****@mindspring.com> wrote:
Keith Thompson wrote:
As far as I know, gcc's treatment of string literals as const doesn't
affect the behavior of any strictly conforming program, cause any
strictly conforming program to fail to compile, or cause any required
diagnostic to fail to appear.


Is there anything you can do with a string literal
in a C program, that you couldn't do if string
literals were const qualified by default?


Assign them to char *s without sprinkling your code with numerous
superfluous (and therefore evil) casts.

Richard
Nov 15 '05 #27

P: n/a
Richard Bos wrote:

pete <pf*****@mindspring.com> wrote:

Is there anything you can do with a string literal
in a C program, that you couldn't do if string
literals were const qualified by default?


Assign them to char *s without sprinkling your code with numerous
superfluous (and therefore evil) casts.


Ah, yes, the subject of this thread!

--
pete
Nov 15 '05 #28

P: n/a

In article <43***********************@news.xs4all.nl>, Skarmander <in*****@dontmailme.com> writes:
Michael Wojcik wrote:
In article <43***********************@news.xs4all.nl>, Skarmander <in*****@dontmailme.com> writes:
gcc is still a C compiler with -Wwrite-strings, since the resulting code
is semantically equivalent to code where string literals are not
const, including undefined behavior for modifying literals.


And if that were the definition of a conforming implementation,
you'd be right. But it is not.
On the other hand, what I wrote is also not the definition of a
conforming implementation, which only has to accept any strictly-
conforming program (relaxed for freestanding implementations), not
alter the behavior of any strictly conforming program, and document
implementation-specified behavior.

For some reason when I posted the above I was thinking that
explicitly contradicting the standard rendered an implementation
non-conforming, but - unintuitive though it might be - it does not.

Someone noted that gcc with -Wwrite-strings -Werror is nonconforming,
because it refuses to accept the following strictly-conforming
program:

int main(void) {char *a = "a"; return 0;}

But just changing the type of string literals alone does not, AFAICT,
make it nonconforming.
In a conforming implementation, character string literals have type
"array of char". Period. C99 6.4.5 does not allow any waffling
about semantic equivalence.


So if gcc acts as a conforming implementation despite this option, gives
warnings when string literals are assigned to non-const pointers, and if
it had not described this effect in its documentation as assigning a
const type to literals, would that still be in violation?


No; I was wrong (though I don't believe the standard defines "in
violation" - I'll take that as a synonym for "nonconforming"). If
it documents -Wwrite-strings as changing the type of string literals,
it contradicts the standard, but this does not make it nonconforming.
If it omits that (to my mind ill-considered) remark in the documenta-
tion, it's not even contradicting the standard.

--
Michael Wojcik mi************@microfocus.com

The presence of those seeking the truth is infinitely preferable to
the presence of those who think they've found it. -- Terry Pratchett
Nov 15 '05 #29

P: n/a

In article <ln************@nuthaus.mib.org>, Keith Thompson <ks***@mib.org> writes:
mw*****@newsguy.com (Michael Wojcik) writes:

In a conforming implementation, character string literals have type
"array of char". Period. C99 6.4.5 does not allow any waffling
about semantic equivalence.


At execution time, nothing really has a type; it's all zeros and ones.


True, but I don't see how that's relevant. The standard doesn't care
about execution, except insofar as a conforming implementation is
required to not alter the behavior of any strictly-conforming program.
On the other hand, the standard *is* quite concerned about the types
of objects.

However, it's all pretty much moot, as I realized that, of course,
explicitly contradicting the standard does not in and of itself render
an implementation nonconforming. See my reply to Skarmander.

--
Michael Wojcik mi************@microfocus.com

Cooperation is just like two pagodas, one hardware and one software.
-- Wen Jiabao
Nov 15 '05 #30

This discussion thread is closed

Replies have been disabled for this discussion.