Strange !!

K

karthikbalaguru

Hi,

I am using Visual C++ 2008 Express edition.
The code is building well, but while execution,
it states that 'A problem caused the program
to stop working correctly. Windows will close
the program and notify you if a solution is
available'

But, i expected the output of 'x1z', but
i did not get that output.

Strange !!
Where is the problem in the below code?

#include<stdio.h>
int main(void)
{
char *a[3]={"def","xyz","qrs"};
*(a[1]+1)='1';
printf("%s",a[1]);
return 0;
}

Thx in advans,
Karthik Balaguru
 
F

Flash Gordon

karthikbalaguru said:
Hi,

I am using Visual C++ 2008 Express edition.

The compiler is irrelevant in this case. What you have is a problem with
your C code.
The code is building well, but while execution,
it states that 'A problem caused the program
to stop working correctly. Windows will close
the program and notify you if a solution is
available'

But, i expected the output of 'x1z', but
i did not get that output.

Strange !!
Where is the problem in the below code?

The problem is that you are trying to modify a string literal, and this
is "not allowed" in C. Unfortunately although you are not allowed to
modify string literals, for historical reasons they are not defined as
being const, so the compiler is not required to warn you and many will
not warn you. However, since you are not allowed to modify them, when
you try the program is allowed to do what you saw, or generate a
"segmentation violation", or do what you expected, or even cause a
little purple monkey to suddenly appear and throw a rotten egg at you.
OK, so the last of these is unlikely to happen, but the point is that
*anything* is allowed to happen as far as the language is concerned, and
sometimes what happens *is* something very uexpected.
#include<stdio.h>
int main(void)
{
char *a[3]={"def","xyz","qrs"};
*(a[1]+1)='1';
printf("%s",a[1]);
return 0;
}

The above is obviously just test code. The best way to solve your
problem with your real code will depend on what you are trying to
achieve. It might involve a character array for each string, or dynamic
memory allocation of the space for each string.
 
K

Kojak

Le Sat, 28 Feb 2009 14:13:34 +0000,
Flash Gordon a écrit :
[...]
The problem is that you are trying to modify a string literal, and
this is "not allowed" in C. Unfortunately although you are not
allowed to modify string literals, for historical reasons they are
not defined as being const, so the compiler is not required to warn
you and many will not warn you.

It might be wiser to write the line this way:

const char *a[3] = { "def", "xyz", "qrs" };

this should help. By example, gcc complain:

error: assignment of read-only location ‘*(a[1] + 1u)’

That is , I have no idea about how behave other compilers.
 
B

Ben Bacarisse

Kojak said:
Le Sat, 28 Feb 2009 14:13:34 +0000,
Flash Gordon a écrit :
[...]
The problem is that you are trying to modify a string literal, and
this is "not allowed" in C. Unfortunately although you are not
allowed to modify string literals, for historical reasons they are
not defined as being const, so the compiler is not required to warn
you and many will not warn you.

It might be wiser to write the line this way:

const char *a[3] = { "def", "xyz", "qrs" };

this should help. By example, gcc complain:

error: assignment of read-only location ‘*(a[1] + 1u)’

That is , I have no idea about how behave other compilers.

The trouble is you only think to mark the chars as const if you know
that literals are not modifiable. Another strategy is turn lost of
warning one. gcc has -Wwrite-strings that makes "xxx" an array of
const chars. This makes gcc non-conforming is some very obscure
corner cases, but that small loss is worth it in my opinion.
 
K

Kojak

Le Sat, 28 Feb 2009 15:22:03 +0000,
Ben Bacarisse a écrit :
The trouble is you only think to mark the chars as const if you know
that literals are not modifiable. Another strategy is turn lost of

Yes indeed, however, it avoid attempt to write, later in the
source, something like this:

*(a[1]+1)='1';

In this case, compiler stop signaling an error.
warning one. gcc has -Wwrite-strings that makes "xxx" an array of
const chars. This makes gcc non-conforming is some very obscure
corner cases, but that small loss is worth it in my opinion.

Yes of course, it's another solution, but, AFAIK and as you guessed
this option isn't relevant for Visual C++, and worse, while compiling
thousand files, it's too easy to override a warning.

sincerely,
 
C

CBFalconer

Ben said:
.... snip ...
It might be wiser to write the line this way:

const char *a[3] = { "def", "xyz", "qrs" };

this should help. By example, gcc complain:

error: assignment of read-only location ‘*(a[1] + 1u)’

That is , I have no idea about how behave other compilers.

The trouble is you only think to mark the chars as const if you
know that literals are not modifiable. Another strategy is turn
lost of warning one. gcc has -Wwrite-strings that makes "xxx"
an array of const chars. This makes gcc non-conforming is some
very obscure corner cases, but that small loss is worth it in my
opinion.

I consider use of such a define, or of the -Wwrite-strings, to be
virtually necessary for any new code. I know of no problems
arising in valid old code. If you do, please spell the "small
loss" out.
 
H

Harald van Dijk

Ben said:
[...] gcc has -Wwrite-strings that makes "xxx" an array of
const chars. This makes gcc non-conforming is some very obscure corner
cases, but that small loss is worth it in my opinion.

I consider use of such a define, or of the -Wwrite-strings, to be
virtually necessary for any new code. I know of no problems arising in
valid old code. If you do, please spell the "small loss" out.

char (*p)[] = &"Hello";

is valid C.

const char (*p)[] = &"Hello";

is invalid C.

gcc, with the -Wwrite-strings option, warns as you would hope for the
first form, but can no longer be convinced to diagnose the second form as
incorrect, even though this violates a constraint.

This is not a problem with valid old code, but there are other
requirements on a conforming implementation than only to accept valid
code.
 
B

Ben Bacarisse

Harald van Dijk said:
Ben said:
[...] gcc has -Wwrite-strings that makes "xxx" an array of
const chars. This makes gcc non-conforming is some very obscure corner
cases, but that small loss is worth it in my opinion.

I consider use of such a define, or of the -Wwrite-strings, to be
virtually necessary for any new code. I know of no problems arising in
valid old code. If you do, please spell the "small loss" out.

char (*p)[] = &"Hello";

is valid C.

const char (*p)[] = &"Hello";

is invalid C.

gcc, with the -Wwrite-strings option, warns as you would hope for the
first form, but can no longer be convinced to diagnose the second form as
incorrect, even though this violates a constraint.

This is not a problem with valid old code, but there are other
requirements on a conforming implementation than only to accept valid
code.

Thank you for saving me the effort. I will admit that I was just
going to refer CBF back to the last time we discussed this. Going
back to look, I see that then the situation was reversed in that you
pointed out the problem and I supplied the example.
 
C

CBFalconer

Ben said:
Harald van Dijk said:
CBFalconer said:
Ben Bacarisse wrote:

[...] gcc has -Wwrite-strings that makes "xxx" an array of
const chars. This makes gcc non-conforming is some very
obscure corner cases, but that small loss is worth it in my
opinion.

I consider use of such a define, or of the -Wwrite-strings, to
be virtually necessary for any new code. I know of no problems
arising in valid old code. If you do, please spell the "small
loss" out.

char (*p)[] = &"Hello";

is valid C.

const char (*p)[] = &"Hello";

is invalid C.

gcc, with the -Wwrite-strings option, warns as you would hope
for the first form, but can no longer be convinced to diagnose
the second form as incorrect, even though this violates a
constraint. This is not a problem with valid old code, but
there are other requirements on a conforming implementation
than only to accept valid code.

Thank you for saving me the effort. I will admit that I was
just going to refer CBF back to the last time we discussed this.
Going back to look, I see that then the situation was reversed
in that you pointed out the problem and I supplied the example.

Thanks Harald, Ben. I don't remember a previous discussion.
 
A

Antoninus Twink

Thanks Harald, Ben. I don't remember a previous discussion.

Given that you probably don't remember what nurse gave you for breakfast
this morning, that's no great surprise.
 

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

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,122
Latest member
VinayKumarNevatia_
Top