For Programmers: Free Programming Magazines  


Home > Archive > VC Language > May 2006 > Is this valid code ?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Is this valid code ?
Polaris

2006-05-20, 4:16 am

Hi Experts:

I have 2 questions about C/C++; is the code below valid? In both cases, the
programs "works". Thanks in advance !

Polaris

Question 1: Is the code correct?
void main ()
{
char * ptr = "Is this Valid?";
cout << ptr << endl;
}

Question 2: Why can I change the const string "test" ?
void main ()
{
const char *ptr = "test";
strcpy ((char*)ptr, "1234");
}


Carl Daniel [VC++ MVP]

2006-05-20, 4:16 am

Polaris wrote:
> Hi Experts:
>
> I have 2 questions about C/C++; is the code below valid? In both
> cases, the programs "works". Thanks in advance !
>
> Polaris
>
> Question 1: Is the code correct?


It's valid, yes.

> void main ()
> {
> char * ptr = "Is this Valid?";
> cout << ptr << endl;
> }
>
> Question 2: Why can I change the const string "test" ?


Because you cast away the constsness. After that, all bets are off. It
could crash the program, raise some sort of exepction, or "work" - all are
equally legal.

> void main ()
> {
> const char *ptr = "test";
> strcpy ((char*)ptr, "1234");
> }


-cd


Mark Randall

2006-05-20, 4:16 am


"Polaris" <etpolaris@hotmail.com> wrote in message
news:emfv018eGHA.2076@TK2MSFTNGP04.phx.gbl...
> Question 1: Is the code correct?
> void main ()
> {
> char * ptr = "Is this Valid?";
> cout << ptr << endl;
> }


It is 'correct' but not... its legacy. You should never assign a string
literal to a char* although most compilers accept it.

> Question 2: Why can I change the const string "test" ?
> void main ()
> {
> const char *ptr = "test";
> strcpy ((char*)ptr, "1234");
> }


You are casting it to un-const. When compiled and the "test" put in the
appropriate memory (marked read only) this should go nuclear with an access
violation.

--
- Mark Randall
http://www.temporal-solutions.co.uk

"We're Systems and Networks..."
"It's our job to know..."


Stefan Näwe

2006-05-20, 7:06 pm

Polaris wrote:

> Hi Experts:
>
> I have 2 questions about C/C++; is the code below valid? In both cases,
> the programs "works". Thanks in advance !
>
> Polaris
>
> Question 1: Is the code correct?
> void main ()


It's:
int main()
- or -
int main(int argc, char* argv[])

*Always!*

> {
> char * ptr = "Is this Valid?";
> cout << ptr << endl;
> }
>
> Question 2: Why can I change the const string "test" ?
> void main ()
> {
> const char *ptr = "test";
> strcpy ((char*)ptr, "1234");
> }


Others have answered that.

/S
--

Jonathan Wood

2006-05-21, 10:09 pm

Mark,

> It is 'correct' but not... its legacy. You should never assign a string
> literal to a char* although most compilers accept it.


Although programmers who want to someday port to Unicode are advised to use
TCHAR and LPTSTR, it is perfectly legal to assing a string literal to a
char*.

Why do you feel that is a problem?

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com


Carl Daniel [VC++ MVP]

2006-05-21, 10:09 pm

"Jonathan Wood" <jwood@softcircuits.com> wrote in message
news:OJ3Z%233TfGHA.2172@TK2MSFTNGP04.phx.gbl...
> Mark,
>
>
> Although programmers who want to someday port to Unicode are advised to
> use TCHAR and LPTSTR, it is perfectly legal to assing a string literal to
> a char*.
>
> Why do you feel that is a problem?


Because the type of a string literal is const char *, not char*. In
general, implicit conversions that lose const-ness are not allowed, but many
compilers allow this one simply because it would break so much existing
code. I don't have my copy of the C++ standard handy to check, but I'm
inclined to say that this implicit loss-of-const is actually standard
conforming as well.

-cd


Jeff Partch [MVP]

2006-05-21, 10:09 pm

"Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@mvps.org.nospam>
wrote in message news:uY$ZBAUfGHA.2456@TK2MSFTNGP04.phx.gbl...
> code. I don't have my copy of the C++ standard handy to check, but I'm


And I thought you had that thing memorized, Carl. :)
--
Jeff Partch [VC++ MVP]


Jonathan Wood

2006-05-21, 10:09 pm

Ah... Yes, a string literal should be considered a constant.

That said, I can think at least one programming task that really could
benefit from this logic. Consider the case where you need to form a string
like "x:\", where x is the current drive. I know there have been times when
I create the string constant and then modify the first character to form my
string. That is useful.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com


"Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@mvps.org.nospam>
wrote in message news:uY$ZBAUfGHA.2456@TK2MSFTNGP04.phx.gbl...
> "Jonathan Wood" <jwood@softcircuits.com> wrote in message
> news:OJ3Z%233TfGHA.2172@TK2MSFTNGP04.phx.gbl...
>
> Because the type of a string literal is const char *, not char*. In
> general, implicit conversions that lose const-ness are not allowed, but
> many compilers allow this one simply because it would break so much
> existing code. I don't have my copy of the C++ standard handy to check,
> but I'm inclined to say that this implicit loss-of-const is actually
> standard conforming as well.
>
> -cd
>
>



Igor Tandetnik

2006-05-21, 10:09 pm

"Jonathan Wood" <jwood@softcircuits.com> wrote in message
news:udK98jUfGHA.5104@TK2MSFTNGP04.phx.gbl
> That said, I can think at least one programming task that really could
> benefit from this logic. Consider the case where you need to form a
> string like "x:\", where x is the current drive. I know there have
> been times when I create the string constant and then modify the
> first character to form my string. That is useful.


Perhaps you could use

char curDrive[] = "x:\\";

and modify curDrive[0] to your heart's content.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Mark Randall

2006-05-21, 10:09 pm

"Jonathan Wood" <jwood@softcircuits.com> wrote:
> I create the string constant and then modify the first character to form
> my string. That is useful.


int _tmain(int argc, _TCHAR* argv[])
{
char* pszTest = "c:\\config.xml";
*pszTest = 'd';
return 0;
}

First-chance exception at 0x00411388 in w32boom.exe:
0xC0000005: Access violation writing location 0x0041563c.
Unhandled exception at 0x00411388 in w32boom.exe:
0xC0000005: Access violation writing location 0x0041563c.

Visual Studio 2005

--
- Mark Randall
http://www.temporal-solutions.co.uk

"We're Systems and Networks..."
"It's our job to know..."


John Carson

2006-05-22, 4:19 am

"Carl Daniel [VC++ MVP]"
<cpdaniel_remove_this_and_nospam@mvps.org.nospam> wrote in message
news:uY$ZBAUfGHA.2456@TK2MSFTNGP04.phx.gbl
> "Jonathan Wood" <jwood@softcircuits.com> wrote in message
> news:OJ3Z%233TfGHA.2172@TK2MSFTNGP04.phx.gbl...
>
> Because the type of a string literal is const char *, not char*. In
> general, implicit conversions that lose const-ness are not allowed,
> but many compilers allow this one simply because it would break so
> much existing code. I don't have my copy of the C++ standard handy
> to check, but I'm inclined to say that this implicit loss-of-const is
> actually standard conforming as well.
>
> -cd



Yes, the conversion is standard-conforming but deprecated --- section 4.2/2.

--
John Carson


Jonathan Wood

2006-05-24, 7:10 pm

I agree--that is useful. But others were pointing out that string literals
were technically constants, and that you really shouldn't use the syntax you
provided.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

"Igor Tandetnik" <itandetnik@mvps.org> wrote in message
news:OhgJsNVfGHA.3588@TK2MSFTNGP02.phx.gbl...
> "Jonathan Wood" <jwood@softcircuits.com> wrote in message
> news:udK98jUfGHA.5104@TK2MSFTNGP04.phx.gbl
>
> Perhaps you could use
>
> char curDrive[] = "x:\\";
>
> and modify curDrive[0] to your heart's content.
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>



Jonathan Wood

2006-05-24, 7:10 pm

Interesting.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

"Mark Randall" < mark[__OKTHISISFAKE_]yr@REMOVETHISgoogle
.ANDTHIScom> wrote
in message news:evycbRVfGHA.1260@TK2MSFTNGP05.phx.gbl...
> "Jonathan Wood" <jwood@softcircuits.com> wrote:
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> char* pszTest = "c:\\config.xml";
> *pszTest = 'd';
> return 0;
> }
>
> First-chance exception at 0x00411388 in w32boom.exe:
> 0xC0000005: Access violation writing location 0x0041563c.
> Unhandled exception at 0x00411388 in w32boom.exe:
> 0xC0000005: Access violation writing location 0x0041563c.
>
> Visual Studio 2005
>
> --
> - Mark Randall
> http://www.temporal-solutions.co.uk
>
> "We're Systems and Networks..."
> "It's our job to know..."
>



Mark Randall

2006-05-24, 7:10 pm

"Jonathan Wood" <jwood@softcircuits.com> wrote in message
news:OXKcxM4fGHA.5092@TK2MSFTNGP04.phx.gbl...
>I agree--that is useful. But others were pointing out that string literals
>were technically constants, and that you really shouldn't use the syntax
>you provided.


The char blah[] = "hello world"; syntax is actually a stack initialiser, the
"Hello World" is copied onto the stack frame at the time it is called,
likely to be memcopied from a read-only section.

Hence the blah is stored in the read / write part of the code.

--
- Mark Randall
http://www.temporal-solutions.co.uk

"We're Systems and Networks..."
"It's our job to know..."


Igor Tandetnik

2006-05-24, 7:10 pm

Jonathan Wood <jwood@softcircuits.com> wrote:
>
> I agree--that is useful. But others were pointing out that string
> literals were technically constants, and that you really shouldn't
> use the syntax you provided.


This syntax is perfectly valid, and curDrive can be legally modified.
Here we don't create a pointer to string literal - we initialize a
character array. The syntax is just a shorthand for

char curDrive[] = {'x', ':', '\', '\', '\0'};

which clearly does not involve any string literals. The array is
writable regardless of what its initializer looks like.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Tamas Demjen

2006-05-24, 7:10 pm

Jonathan Wood wrote:
> I agree--that is useful. But others were pointing out that string literals
> were technically constants, and that you really shouldn't use the syntax you
> provided.


But that's not a string literal. There's a huge difference between

char* test = "c:\\config.xml";
*test = 'd';

and

char test[] = "c:\\config.xml";
*test = 'd';

The first one is a string literal. In fact, it should toss at least a
warning message, since you're trying to assign a const char* to a char*.
Your string is located in read-only memory, and any modification to it
throws an access violation (it's a hardware exception due to writing
read-only memory).

The second case, however, is not a string literal, it's a character
array. The compiler treats it like this:

char test[] = { 'c', ':', '\', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'x',
'm', 'l', '\0' };

It's an array on the stack, which you can freely modify.

The first example crashes with VC++ 2005. The second one doesn't, it's
perfectly valid code.

Also note that in the first example, sizeof(test) is 4 (a pointer),
while in the second example sizeof(test) == 15 == strlen(test) + 1.

Tom
Carl Daniel [VC++ MVP]

2006-05-24, 7:10 pm

"Jonathan Wood" <jwood@softcircuits.com> wrote in message
news:uYYrKN4fGHA.3860@TK2MSFTNGP02.phx.gbl...
> Interesting.


Note that it could just have well "worked". The compiler is allowed to
place constants (such as string literals) in read-only memory, but it's
certainly not obligated to do so. Hence the phrase "undefined behavior".

-cd


Duane Hebert

2006-05-24, 7:10 pm


"Tamas Demjen" <tdemjen@yahoo.com> wrote in message
news:eMPMja4fGHA.2032@TK2MSFTNGP02.phx.gbl...
> Jonathan Wood wrote:


> The first example crashes with VC++ 2005.


A bit annoying that it builds without warning.


Igor Tandetnik

2006-05-24, 7:10 pm

"Duane Hebert" <spoo@flarn2.com> wrote in message
news:OdW7%23t4fGHA.1792@TK2MSFTNGP03.phx.gbl
> "Tamas Demjen" <tdemjen@yahoo.com> wrote in message
> news:eMPMja4fGHA.2032@TK2MSFTNGP02.phx.gbl...
>
>
> A bit annoying that it builds without warning.


There are lots of const-incorrect functions around, as C only got const
keyword very recently. If you have a library function f(char*) which you
know treats the parameter as read-only, it would be extremely annoying
to get a warning every time you call it as f("some literal")
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com