James said:
Pete Becker wrote:
On 2007-09-02 06:43:07 -0400, Gianni Mariani <gi3nos...@mariani.ws> 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.)