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
|
|
|
|
|