String Constant absent in C++

  • Thread starter karthikbalaguru
  • Start date
J

James Kanze

karthikbalaguru wrote:
No it won't, because str1 isn't a const.

It might, or it might not. The expression "*str1 = 'M'"
attempts to modify a character in a string literal. In both C
and C++, this is undefined behavior (albeit for slightly
different reasons). Historically:

1. In K&R C, there was no const. In addition, K&R guaranteed
that 1) all string literals occupied distinct storage, and
2) that they could be modified. This last ability was
considered a defect by many, so...

2. The C standards committee declared that it was undefined
behavior to attempt such a modification (an implementation
could put the literal in write-only memory), and that it was
unspecified whether two identical string literals occupied
distinct memory or not.

The C standards committee also adopted the const keyword
from C++, but decided not to apply it to the type (char[])
of a string literal.

3. In C++, const plays a much larger role than in C. (E.g. it
is involved in function overload resolution.) For this
reason, the C++ committee decided that the type of a string
literal must be char const[], and not simply char[]. Still,
it was quite obvious that they couldn't responsibly break
things like ``char* p = "abc" ;'', so they introduced a
special conversion, which only applies in specific cases
(and which could easily cause a compiler warning when used).

For historical reasons, most C++ compilers still have an option
to treat string literals as they were treated in K&R C: as
writable objects, with guaranteed separate data for each
literal. And even today, this is the default for some
compilers (Sun CC, for example).
Some C++ compilers will warn that a string literal is being assigned to
a char*

I think that the committee really wanted to encourage such
warnings.
 
R

red floyd

James said:
It might, or it might not. The expression "*str1 = 'M'"
attempts to modify a character in a string literal. In both C
and C++, this is undefined behavior (albeit for slightly
different reasons). Historically:
2. The C standards committee declared that it was undefined
behavior to attempt such a modification (an implementation
could put the literal in write-only memory),

Now *THAT* would be an interesting decision by the implementor. :)
I know you meant to say "read-only memory".
 
O

Old Wolf

karthikbalaguru said:
Further from Peter's reply. I conclude.
In both C and C++ str1 is a constant pointer to char.

Peter's reply was wrong. str1 is a non-const pointer to
char, in both languages. A constant pointer to char
would look like:
char *const str1
An attempt to
modify it causes undefined
behaviour. The correct way to initialise such a pointer is to remember
the const:
eg.

char const* str1 = "Cplusplus".

char* is a special case and the only place where you can leave out the
const. It was made special in
order to faciliate porting old C and C++ code.

Thx,
Karthik Balaguru

The above text has been copied verbatim from peter koch's
post. You should use some kind of quote marking
mechanism when you do this, otherwise it looks
like you are plagiarizing somebody else's ideas.
 
C

CBFalconer

red said:
James Kanze wrote:
.... snip ...


Now *THAT* would be an interesting decision by the implementor. :)
I know you meant to say "read-only memory".

Just in case needed, Signetics is the only manufacturer to have
ever produced a documented guaranteed performance write-only memory
chip. I think they have a lock on the trade. :)
 
R

red floyd

CBFalconer said:
Just in case needed, Signetics is the only manufacturer to have
ever produced a documented guaranteed performance write-only memory
chip. I think they have a lock on the trade. :)

Wasn't it *Signutics*, not Signetics? Though Signetics did publish
Signutics' spec.
 
R

Richard Bos

red floyd said:
Wasn't it *Signutics*, not Signetics? Though Signetics did publish
Signutics' spec.

No. "The Signetics 25000 Series 9046XN Random Access Write-Only-Memory"
is what my PDF of that spec calls it.

Richard
 
J

James Kanze

No. "The Signetics 25000 Series 9046XN Random Access Write-Only-Memory"
is what my PDF of that spec calls it.

Now that brings back memories. Of course, at the time (early
1970's), a lot of manufacturers were producing write only
memory. They just didn't document the fact. And "random
access" meant just that: you read or wrote at a random address.
(I once worked on a system which every once in a
while---typically once every three or four hours---would set one
randomly chosen bit every 128 bytes to 1. Very irritating when
some of the bytes were part of your program. Gave a whole new
dimension to the notion of "self modifying code".)
 
G

Gianni Mariani

James said:
Knowing what you know today, would the reason you gave here be a worthy
reason to make the same decision again or if you could go back in time,
would you vote to not allow string literals to be assign to a char *?

The decision was the only possible one. Anything else would
have broken too much code. It would have been absolutely
unacceptable to have made something like:
char* p = "abc" ;
to have been illegal. The only choice was in the mechansim
which is used to allow it. The C committee simply made the type
of "abc" char[4], and said that despite a non-const type, it was
undefined behavior to attempt to modify it. The C++ committee
went a step further, and said that "abc" had type char const[4],
but introduced a very special conversion to allow the above to
work.

I don't mean to sound like a troll but I honestly am not convinced.

What I would like to see normally happen in a case like this one is to
bite the bullet but allow the compiler supplier to provide a backwards
computability flag that allowed something like this rather than mandate
it in the standard. Instead now we have newbies completely surprised
where I mean "badly" surprised.

I have often needed to "clean up" a large codebase. For somthing like
this, I imagine that it can be made fairly mechanical. I've warmed up
the macro processor on my editor or written a little lex script a couple
of times to modify a few hundred files at a time and was quite surprised
that it worked first time which is usually the case when it's a
mechanical process.

Anyhow, I think this is one of those cases where the cure is far worse
than the problem.
 
J

James Kanze

James said:
Pete Becker wrote:
On 2007-09-02 06:43:07 -0400, Gianni Mariani <[email protected]> said:
...
The reason is that historically, C-style strings were not always
constant, and there was code that relied on this. The rule in C++ is
that the type of a string literal is array-of-const-char. The literal
can be converted into a pointer-to-char, but that you write to it at
your peril. That preserves the status quo. The conversion is deprecated,
so portable code should not rely on it.
Knowing what you know today, would the reason you gave here be a worthy
reason to make the same decision again or if you could go back in time,
would you vote to not allow string literals to be assign to a char *?
The decision was the only possible one. Anything else would
have broken too much code. It would have been absolutely
unacceptable to have made something like:
char* p = "abc" ;
to have been illegal. The only choice was in the mechansim
which is used to allow it. The C committee simply made the type
of "abc" char[4], and said that despite a non-const type, it was
undefined behavior to attempt to modify it. The C++ committee
went a step further, and said that "abc" had type char const[4],
but introduced a very special conversion to allow the above to
work.
I don't mean to sound like a troll but I honestly am not convinced.

The standard is a contract of sorts. The first version of a
standard should treat any existing de facto standards as a
previous version. Changes which break existing code violate the
contract.

Obviously, it's not an absolute. You have to weigh the
advantages versus the amount of existing code which will be
broken. In this case, at the time the standard was being
written, it was pretty clear that not allowing ``char* p =
"xyz";'' would break a lot of code---perhaps most of the
existing code at the time. The "advantage" is that a few, rare
errors would be caugt be the compiler. In this case, the
cost-benefits analysis weighs (or weighed---the decision must be
considered in its historical context) so extremely heavily to
one side that no one even seriously suggested breaking the code.
What I would like to see normally happen in a case like this one is to
bite the bullet but allow the compiler supplier to provide a backwards
computability flag that allowed something like this rather than mandate
it in the standard. Instead now we have newbies completely surprised
where I mean "badly" surprised.

I fail to see where newbies would be surprised. They should be
taught to write ``char const* p = "xyz";'', and of course, that
works. (They should also be taught that in general, that the
fact that the compiler doesn't complain doesn't mean that the
code is correct.)
I have often needed to "clean up" a large codebase.

The problem isn't only having to "clean up" your own codebase.
The problem is also interfacing with legacy code. But of
course, most organizations don't like having to make changes in
working code, either. For good reasons.
For somthing like this, I imagine that it can be made fairly
mechanical.

I rather doubt it.
I've warmed up
the macro processor on my editor or written a little lex script a couple
of times to modify a few hundred files at a time and was quite surprised
that it worked first time which is usually the case when it's a
mechanical process.

In this case, of course, you'd have to parse enough C++ to
recognize the declarations, then analyse the initialization to
see if it is a string literal (which often will be a #define, so
you'd have to preprocess as well).
Anyhow, I think this is one of those cases where the cure is far worse
than the problem.

I don't think you understand the problem. Or rather, the
problems. The current situation isn't very elegant, but it
doesn't really cause any serious problems in production (and the
intent of the committee was that compilers would *warn* when
this special conversion was used---that's one of the reasons why
the C solution wasn't adopted). And the impact of a change
would be enormous, even today. (Note that "const-correctness"
is not considered particularly important in the C community, and
many C interfaces, even today, will use "char*" even if the
function doesn't change anything. And many C++ programs will
use such interfaces.)
 
K

karthikbalaguru

Peter's reply was wrong. str1 is a non-const pointer to
char, in both languages. A constant pointer to char
would look like:
char *const str1





The above text has been copied verbatim from peter koch's
post. You should use some kind of quote marking
mechanism when you do this, otherwise it looks
like you are plagiarizing somebody else's ideas.

Apologies, Hereafter, i will use some kind of quote marking mechanism
while highlighting those.

Thx,
Karthik Balaguru
 
C

Charles Richmond

CBFalconer said:
Just in case needed, Signetics is the only manufacturer to have
ever produced a documented guaranteed performance write-only memory
chip. I think they have a lock on the trade. :)

It was in the specification book right next to the
sound emitting diode. When connected across 12,000 volts,
the diode would emit a loud POP... but only once. ;-)
 

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
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top