String literals non const?

  • Thread starter Marcin Kalicinski
  • Start date
M

Marcin Kalicinski

Why string literals are regarded as char * not as const char *?

(1) void f(char *);
(2) void f(const char *);

f("foo") will call version (1) of function f.

I understand that the exact type of literal "foo" is char[4], which by means
of standard conversion becomes char *. Still, there's something going wrong
here, because this allows modification of "foo", which in my opinion should
be forbidden (because it causes undefined behavior).

Best regards,
Marcin
 
J

Jacques Labuschagne

Marcin said:
Why string literals are regarded as char * not as const char *?

(1) void f(char *);
(2) void f(const char *);

f("foo") will call version (1) of function f.

I understand that the exact type of literal "foo" is char[4], which by means
of standard conversion becomes char *. Still, there's something going wrong
here, because this allows modification of "foo", which in my opinion should
be forbidden (because it causes undefined behavior).

Best regards,
Marcin

It should be const. Section 2.13.4.1 states
``An ordinary string literal has type "array of n const char" and a
static storage duration where n is the size of the string as
defined below, and is initialized with the given characters.''

HTH,
Jacques
 
M

Marcin Kalicinski

Hi,

So it seems there's something wrong with VC++ .NET compiler. The following
code:

//==========================
#include <iostream>
void main()
{
std::cout << typeid("foo").name() << "\n";
}
//==========================

Outputs "char[4]". And the following one:

//==========================
#include <iostream>
int f(char *) { return 1; }
int f(const char *) { return 2; }
void main()
{
std::cout << f("foo") << "\n";
}
//==========================

Outputs 1.

At the moment I do not have access to any other compiler, but I wonder if
this is normal behavior? If the standard says it should be const char [4],
it's a serious problem if this is char[4] instead.

Best regards,
Marcin
Marcin said:
Why string literals are regarded as char * not as const char *?

(1) void f(char *);
(2) void f(const char *);

f("foo") will call version (1) of function f.

I understand that the exact type of literal "foo" is char[4], which by means
of standard conversion becomes char *. Still, there's something going wrong
here, because this allows modification of "foo", which in my opinion should
be forbidden (because it causes undefined behavior).

Best regards,
Marcin

It should be const. Section 2.13.4.1 states
``An ordinary string literal has type "array of n const char" and a
static storage duration where n is the size of the string as
defined below, and is initialized with the given characters.''

HTH,
Jacques
 
J

Jacques Labuschagne

Marcin said:
Hi,

So it seems there's something wrong with VC++ .NET compiler. The following
code:

//==========================
#include <iostream>
void main()
{
std::cout << typeid("foo").name() << "\n";
}
//==========================

Outputs "char[4]". And the following one:


Interestingly enough, GCC 3.2.3 doesn't show the difference between
char[] and const char[] through typeid.name() -
cout << typeid(char[4]).name() << '\n'
<< typeid(const char[4]).name();
says
A4_c
A4_c

It calls the correct function though.. it matches void f(const char*).

HTH,
Jacques.
 
S

Sumit Rajan

Marcin Kalicinski said:
//==========================
#include <iostream>
int f(char *) { return 1; }
int f(const char *) { return 2; }
void main()
{
std::cout << f("foo") << "\n";
}
//==========================

Outputs 1.

On changing void main() to int main() and compiling using Comeau C++, the
output is 2. On mingw, the output is 2.

Curiously, the output is 1 on Borland 5.5.1.

Regards,
Sumit.
 
M

Magnus

Marcin Kalicinski said:
Hi,

So it seems there's something wrong with VC++ .NET compiler. The following
code:

//==========================
#include <iostream>
void main()
{
std::cout << typeid("foo").name() << "\n";
}
//==========================

Outputs "char[4]". And the following one:

//==========================
#include <iostream>
int f(char *) { return 1; }
int f(const char *) { return 2; }
void main()
{
std::cout << f("foo") << "\n";
}
//==========================

This outputs 2 on Visual Studio .NET 2003 or VC++ 7.1

- Magnus
 
M

Marcin Kalicinski

Hi,

I tested it on VC .NET (not 2003), compiler version 13.00.9466. Seems that
Microsoft are fixing their bugs :)

Best regards,
Marcin

U¿ytkownik "Magnus said:
Marcin Kalicinski said:
Hi,

So it seems there's something wrong with VC++ .NET compiler. The following
code:

//==========================
#include <iostream>
void main()
{
std::cout << typeid("foo").name() << "\n";
}
//==========================

Outputs "char[4]". And the following one:

//==========================
#include <iostream>
int f(char *) { return 1; }
int f(const char *) { return 2; }
void main()
{
std::cout << f("foo") << "\n";
}
//==========================

This outputs 2 on Visual Studio .NET 2003 or VC++ 7.1

- Magnus
 
R

Ron Natalie

Marcin Kalicinski said:
Why string literals are regarded as char * not as const char *?

(1) void f(char *);
(2) void f(const char *);

f("foo") will call version (1) of function f.
Your compiler is broken. There are two "exact match"
conversion sequences from string literal to char* and const char*.
The overloads above are ambiguous.

There is a deprecated conversion from string literal to char* which exists to
codify 25 years of sloppy C programming.
 
D

David White

Jacques Labuschagne said:
Marcin said:
Why string literals are regarded as char * not as const char *?

(1) void f(char *);
(2) void f(const char *);

f("foo") will call version (1) of function f.

I understand that the exact type of literal "foo" is char[4], which by means
of standard conversion becomes char *. Still, there's something going wrong
here, because this allows modification of "foo", which in my opinion should
be forbidden (because it causes undefined behavior).

The conversion to char * is allowed for compatibility with lots of old code
that uses char * as though it were const char *.
It should be const. Section 2.13.4.1 states
``An ordinary string literal has type "array of n const char" and a
static storage duration where n is the size of the string as
defined below, and is initialized with the given characters.''

There's also 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"; a wide string literal can be converted to an rvalue of type "pointer
to wchar_t". In either case,
the result is a pointer to the first element of the array. This conversion
is considered only when there is an
explicit appropriate pointer target type, and not when there is a general
need to convert from an lvalue to an rvalue. [Note: this conversion is
deprecated. See Annex D. ] For the purpose of ranking in overload resolution
(13.3.3.1.1), this conversion is considered an array to pointer conversion
followed by a qualification conversion (4.4). [Example: "abc" is converted
to "pointer to const char" as an array to pointer conversion, and then to
"pointer to char" as a qualification conversion. ]

DW
 
C

Chris Mantoulidis

Marcin Kalicinski said:
Hi,

So it seems there's something wrong with VC++ .NET compiler. The following
code:


M$ products, BAH!!!!

My GCC 3.3.2 will work fine with that and call the const char * version

//==========================
#include <iostream>
void main()
{
std::cout << typeid("foo").name() << "\n";
}
//==========================

Outputs "char[4]". And the following one:

//==========================
#include <iostream>
int f(char *) { return 1; }
int f(const char *) { return 2; }
void main()
{
std::cout << f("foo") << "\n";
}
//==========================

Outputs 1.

At the moment I do not have access to any other compiler, but I wonder if
this is normal behavior? If the standard says it should be const char [4],
it's a serious problem if this is char[4] instead.

Best regards,
Marcin
Marcin said:
Why string literals are regarded as char * not as const char *?

(1) void f(char *);
(2) void f(const char *);

f("foo") will call version (1) of function f.

I understand that the exact type of literal "foo" is char[4], which by means
of standard conversion becomes char *. Still, there's something going wrong
here, because this allows modification of "foo", which in my opinion should
be forbidden (because it causes undefined behavior).

Best regards,
Marcin

It should be const. Section 2.13.4.1 states
``An ordinary string literal has type "array of n const char" and a
static storage duration where n is the size of the string as
defined below, and is initialized with the given characters.''

HTH,
Jacques
 
T

tom_usenet

Your compiler is broken. There are two "exact match"
conversion sequences from string literal to char* and const char*.
The overloads above are ambiguous.

No they aren't. string literal -> char* is equivalent to an
array-to-pointer conversion followed by a qualification conversion,
whereas -> const char* is just an array-to-pointer conversion. (2)
will be chosen unambiguously.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 

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
474,159
Messages
2,570,883
Members
47,414
Latest member
djangoframe

Latest Threads

Top