Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Any compiler ANSI C++ compliant? None I found

1 view
Skip to first unread message

vl106

unread,
Nov 15, 2006, 5:18:57 PM11/15/06
to
I was fiddling around with a problem when I ran into an issue that struke
me.
The following code causes an access violation. Correct. "123" is an array of
const char (that's what the standard says).

Okay. By why do all compilers accept this code? foo("123") should produce
a type mismatch error.

At least Scott Meyers has the same opinion:

[...] is technically illegal (it's a violation of const correctness). In
practice, I expect
all compilers to accept such code [...]

I tested Comeau, Digital, Visual and Watcom. All of them accepted the code.
Most binaries worked - only VC crashed as the compiler put the literal in a
const segment.

I for my part plead for C++ leaving its ancestry behind and become a real
typesafe
language!

void foo (char* p) { // accepts "123" and fails!
*p = 'X';
}

int main () {
char s[] = "ABC";
foo (s);
foo ("123"); // Visual C++ will crash!
// Digital, Watcom C++ won't crash!
return 0;
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Thomas Richter

unread,
Nov 15, 2006, 9:08:38 PM11/15/06
to
vl106 wrote:

> I was fiddling around with a problem when I ran into an issue that struke
> me.
> The following code causes an access violation. Correct. "123" is an array of
> const char (that's what the standard says).

But it also says that you can assign a string literal to a char *,
simply because C allowed it.

> Okay. By why do all compilers accept this code? foo("123") should produce
> a type mismatch error.

No, see above.

> At least Scott Meyers has the same opinion:
>
> [...] is technically illegal (it's a violation of const correctness). In
> practice, I expect
> all compilers to accept such code [...]

It is technically illegal, but an exception that is allowed for
backwards compatibility.

> I tested Comeau, Digital, Visual and Watcom. All of them accepted the code.
> Most binaries worked - only VC crashed as the compiler put the literal in a
> const segment.

Which is also a valid thing to do, because you're writing into a
constant string and thus triggering undefined behavior. Everything can
happen, including nothing, or a crash. Note that "..." *has still* the
type const char[], and not char[]. It can only be assigned to a char *,
with all possible side-effects you should be worried about.

> I for my part plead for C++ leaving its ancestry behind and become a real
> typesafe
> language!

Why do you then use char * and not std::string? (-:

So long,
Thomas

red floyd

unread,
Nov 15, 2006, 9:06:54 PM11/15/06
to
vl106 wrote:
> I was fiddling around with a problem when I ran into an issue that struke
> me.
> The following code causes an access violation. Correct. "123" is an array of
> const char (that's what the standard says).

It's UB -- accessing a const via a non-const pointer.

> Okay. By why do all compilers accept this code? foo("123") should produce
> a type mismatch error.


4.2/2 "A string literal (2.13.4) that is not a wide string literal can
be converted to an rvalue of type "pointer to char"; ... [Note: this
conversion is deprecated. See Annex D. ]"

loufoque

unread,
Nov 15, 2006, 9:05:57 PM11/15/06
to
vl106 wrote:
> void foo (char* p) { // accepts "123" and fails!

Try GCC with -Wwrite-strings

peter koch larsen

unread,
Nov 15, 2006, 9:05:04 PM11/15/06
to

vl106 skrev:

> I was fiddling around with a problem when I ran into an issue that struke
> me.
> The following code causes an access violation. Correct. "123" is an array of
> const char (that's what the standard says).
>
> Okay. By why do all compilers accept this code? foo("123") should produce
> a type mismatch error.

(the code in question being void foo (char* p) )

This is because there is one exception to this const correctnes - the
implicit conversion from constant literal character array to char* is
allowed - apparently because lots of legacy code that would otherwise
stop to compile.

[snip]


>
> I for my part plead for C++ leaving its ancestry behind and become a real
> typesafe
> language!
>

That statement is a bit heash! I would love compilers to give a warning
for that conversion, but they can not (in any mode) diagnose it as an
error.
[snip]

/Peter

Hyman Rosen

unread,
Nov 15, 2006, 9:09:06 PM11/15/06
to
vl106 wrote:
> Okay. By why do all compilers accept this code?

Because 4.2/2 explicitly makes it legal (but deprecated).

Alberto Ganesh Barbati

unread,
Nov 15, 2006, 9:09:56 PM11/15/06
to
vl106 ha scritto:

> I was fiddling around with a problem when I ran into an issue that struke me.
> The following code causes an access violation. Correct. "123" is an array of
> const char (that's what the standard says).
>
> Okay. By why do all compilers accept this code? foo("123") should produce
> a type mismatch error.

Because the standard explicitly requires this conversion in §4.2/2
(although it's deprecated). So the behavior you are experiencing is
actually compliant to the standard.

> I for my part plead for C++ leaving its ancestry behind and become a real
> typesafe language!

Completely agree.

Ganesh

PS: all compilers you have tested (except maybe for Comeau) are known to
be non-compliant, but not for this reason ;-)

Carl Barron

unread,
Nov 15, 2006, 9:24:51 PM11/15/06
to
In article <455b6cb8$0$5726$9b4e...@newsspool3.arcor-online.net>,
vl106 <vl...@hotmail.com> wrote:

> I was fiddling around with a problem when I ran into an issue that struke
> me.
> The following code causes an access violation. Correct. "123" is an array of
> const char (that's what the standard says).
>
> Okay. By why do all compilers accept this code? foo("123") should produce
> a type mismatch error.
>
> At least Scott Meyers has the same opinion:
>
> [...] is technically illegal (it's a violation of const correctness). In
> practice, I expect
> all compilers to accept such code [...]
>

Not so sure, char s[] = "ABC"; is a non const char array large
enough to hold "ABC" and intialized with the data of "ABC", not a
pointer to the const "ABC". That is it is a COPY of "ABC" not "ABC".


> I tested Comeau, Digital, Visual and Watcom. All of them accepted the code.
> Most binaries worked - only VC crashed as the compiler put the literal in a
> const segment.
>
> I for my part plead for C++ leaving its ancestry behind and become a real
> typesafe
> language!
>
> void foo (char* p) { // accepts "123" and fails!
> *p = 'X';
> }
>
> int main () {
> char s[] = "ABC";
> foo (s);
> foo ("123"); // Visual C++ will crash!
> // Digital, Watcom C++ won't crash!
> return 0;
> }

Off hand I would say that your VC++ is non compliant. It is treating
it as if main() began with
int main()
{
char *s = "ABC";
// ...
}
which not the same as your main(). Your main says s is a char[4]
intialized to {'A','B','C','\0'} not a pointer to "ABC"; and as such
foo should work with no faults or exceptions.

Maybe you should plead for compliance of your compiler and not
modification of the standard to match a non compliant compiler.

BTW my CW 9 works with your code s becomes "XBC", as expected.

Jiang

unread,
Nov 15, 2006, 9:23:09 PM11/15/06
to
vl106 wrote:
> I was fiddling around with a problem when I ran into an issue that struke
> me.
> The following code causes an access violation. Correct. "123" is an array of
> const char (that's what the standard says).
>
> Okay. By why do all compilers accept this code? foo("123") should produce
> a type mismatch error.
>


No, although normal string literal's type is "array of N const char",
but according to 4.2 "array-to-pointer conversion", we have a standard
conversion ( deprecated one ) from string literal to "pointer to char".


BTW, In the old days, string literal's type was "array of N char".
The const was added to improve the typing system of C++.
See below.

> At least Scott Meyers has the same opinion:
>
> [...] is technically illegal (it's a violation of const correctness). In
> practice, I expect
> all compilers to accept such code [...]
>

As explained, the code is valid, but deprecated.

The rationale can be found at Annex C&D,

[quote]

Subclause _lex.string:

Change:String literals made const

The type of a string literal is changed from "array of char" to
"array
of const char." The type of a wide string literal is changed from
"array of wchar_t" to "array of const wchar_t."

Rationale: This avoids calling an inappropriate overloaded function,
which might expect to be able to modify its argument.

Effect on original feature:Change to semantics of well-defined feature.

Difficulty of converting: Simple syntactic transformation, because
string
literals can be converted to char*; (4.2). The most common cases are
handled by a new but deprecated standard conversion:
char* p = "abc"; // valid in C, deprecated in C + +
char* q = expr ? "abc" : "de"; // valid in C, invalid in C + +

How widely used: Programs that have a legitimate reason to treat string

literals as pointers to potentially modifiable memory are probably
rare.

> I tested Comeau, Digital, Visual and Watcom. All of them accepted the code.
> Most binaries worked - only VC crashed as the compiler put the literal in a
> const segment.
>


They are correct according to the standard.

However, some of them will issue warning/remark for you.
For example, gcc will warn you if you specify the -Wwrite-strings
flag.

$ gcc -Wwrite-strings sl.cpp
sl.cpp: In function `int main()':
sl.cpp:9: warning: deprecated conversion from string constant to
`char*'


> I for my part plead for C++ leaving its ancestry behind and become a real
> typesafe
> language!
>


Well, I do not see any difficulties to prohibit the *new* deprecated
conversion. However, this will break lots of legacy code and I do
not see the benefit. For this issue I see the design trade-off and
I believe this kind of trade-offs made C++ a both usable/productive
and type-safe (strong, or weak. I donot really care about it) language.

BTW, I suggest you read D&E, which shows me lots of points
for how to make a choice. Yes, making a choice is always difficult.

0 new messages