why is this bad

G

Gernot Frisch

char* s=" ";

int main()
{
strcpy(s, "Hello World");
}

This program crashes nicely. I think s is a pointer to a string that
is stored in the executable memory, so the strcpy will overwrite part
of the program, right?

I would not do this, but I found this error and I want to be able to
explain it to the one who wrote it.
Thank you,

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
 
A

alexmdac

I guess the string literal is stored in read-only memory. Try
char sz[256] = " ";
//etc.
 
W

William Payne

Gernot Frisch said:
char* s=" ";

int main()
{
strcpy(s, "Hello World");
}

This program crashes nicely. I think s is a pointer to a string that is
stored in the executable memory, so the strcpy will overwrite part of the
program, right?

I would not do this, but I found this error and I want to be able to
explain it to the one who wrote it.
Thank you,

--
-Gernot
int main(int argc, char** argv) {printf ("%silto%c%cf%cgl%ssic%ccom%c",
"ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com

String literalts are really of type const char* (even though you declared
yours as just char*), that's probably the reason for the crash.
So when declaring string literals always use type const char* so the
compiler can catch such errors...if you want to modify the string, declare
it as:
char foo[] = { "hello" };

/ WP
 
R

Risto Lankinen

William Payne said:
String literalts are really of type const char* (even though you declared
yours as just char*), that's probably the reason for the crash.

The interesting bit, of course, is why does C++ type mechanism
allow you to initialize an object of type <char *> with something
that really is a <const char *> ?!?

IMO that's a flaw in C++ type mechanism.

- Risto -
 
P

Peter Koch Larsen

Risto Lankinen said:
The interesting bit, of course, is why does C++ type mechanism
allow you to initialize an object of type <char *> with something
that really is a <const char *> ?!?

IMO that's a flaw in C++ type mechanism.

- Risto -
It sure is! Well - it sure isn't! It is a left-over from C, kept for
portability reasons.

/Peter
 
R

Rolf Magnus

Risto said:
The interesting bit, of course, is why does C++ type mechanism
allow you to initialize an object of type <char *> with something
that really is a <const char *> ?!?

Usually, it doesn't. You cannot remove constness without a cast, but...
since there is so much C code (and maybe old C++ code) that lets non-const
char* point to string literals, those are an exception to that rule.
IMO that's a flaw in C++ type mechanism.

It's not a bug, it's a feature.
 
K

Karl Heinz Buchegger

Risto said:
The interesting bit, of course, is why does C++ type mechanism
allow you to initialize an object of type <char *> with something
that really is a <const char *> ?!?

IMO that's a flaw in C++ type mechanism.

It is, but it is there for a (once) good reason:
For compatibility with its ancestor: C
 
G

Gernot Frisch

IMO that's a flaw in C++ type mechanism.
It is, but it is there for a (once) good reason:
For compatibility with its ancestor: C

IMO: if it's bound to crash, it should give a warning at compile time.
 
M

msalters

Gernot said:
IMO: if it's bound to crash, it should give a warning at compile
time.

It does - at least at all compilers I use. You probably have your
warning level set way too low - but if you're maintaining older
code, that may be required to ignore all the bugs in the code.
Regards,
Michiel Salters
 
A

Andrey Tarasevich

William said:
String literalts are really of type const char* (even though you declared
yours as just char*), that's probably the reason for the crash.

Firstly, string literals in C++ are really of type 'const char[N+1]'
(where N is the length of the string), not 'const char*'

Secondly, casting away constness and modifying anything through a
pointer of type 'const char*' alone is not enough to cause a crash.
Whether the crash (or more formally, undefined behavior) will occur
depends solely on the modifiability of the object pointed by the pointer.

In this particular case the object pointed by the pointer is not
modifiable. That's why the code causes undefined behavior (manifested as
a crash is this case).
 
A

Andrey Tarasevich

Gernot said:
IMO: if it's bound to crash, it should give a warning at compile time.
...

It is not necessarily bound to crash. For example, forceful removal of
constness is a well-established implementational idiom in C language and
no one is saying that it is "bound to crash". There's no reason why it
should suddenly be "bound to crash" in C++. One just needs to learn to
use such things with proper care. The real problem here is that some
people use such features without even noticing, without understanding
what they've just done.

Don't get me wrong though, I'm all against this deprecated feature of
C++ language. I'm just against perceiving such things as something
necessarily "bound to crash".
 
J

Jack Klein

The interesting bit, of course, is why does C++ type mechanism
allow you to initialize an object of type <char *> with something
that really is a <const char *> ?!?

IMO that's a flaw in C++ type mechanism.

- Risto -

As others have pointed out, it is for comparability with existing C
code. And as for why C allowed and still allows it, there were string
literals in C for about 15 years before there was a 'const' keyword.
 
J

Jack Klein

It is not necessarily bound to crash. For example, forceful removal of
constness is a well-established implementational idiom in C language and
no one is saying that it is "bound to crash". There's no reason why it
should suddenly be "bound to crash" in C++. One just needs to learn to
use such things with proper care. The real problem here is that some
people use such features without even noticing, without understanding
what they've just done.

Don't get me wrong though, I'm all against this deprecated feature of
C++ language. I'm just against perceiving such things as something
necessarily "bound to crash".

There is no forceful removal of "constness" involved when this code is
compiled as C.

Unlike C++, in C the type of a string literal is NOT "array of const
char", it is "array of char". So there is no need to remove the const
qualifier, because it neither exists nor is implied.

Attempting to modify a string literal in C is undefined behavior not
because the chars are const, but because the C standard specifically
states that it is undefined.
 
A

Andrey Tarasevich

Jack said:
There is no forceful removal of "constness" involved when this code is
compiled as C.

I'm not saying that there is one in this particular code. All I'm trying
to say is that existence of a modification-allowing access path to
non-modifiable data does not necessarily lead to a problem. It is not a
good thing most of the time, but it has its uses.
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top