pre ANSI code and writable-strings?

P

Paul Connolly

char *s = "Hello";
s[0] = 'J';
puts(s);

might print "Jello" in a pre-ANSI compiler - is the behaviour of this
program undefined in any pre-ANSI compiler - or would it always have printed
"Jello" with a pre-ANSI compiler?
In gcc with the "writable-strings" option this program prints
Jello
If there were more than one semantics for what this progran did under a
pre-ANSI compiler, which semantics were chosen by gcc for the
"writable-strings" option, and for what reason?
 
G

Gordon Burditt

char *s = "Hello";
s[0] = 'J';
puts(s);

might print "Jello" in a pre-ANSI compiler - is the behaviour of this
program undefined in any pre-ANSI compiler - or would it always have printed
"Jello" with a pre-ANSI compiler?

Since there is no pre-ANSI C standard, anything a pre-ANSI compiler
does is undefined.
In gcc with the "writable-strings" option this program prints
Jello

There are no "compiler options" in ANSI C, there are only different
implementations. The number of combinations of such compiler options
can make the number of implementations enormous. In this case,
both "writable-strings" and non-"writable-strings" can conform to
ANSI C.
If there were more than one semantics for what this progran did under a
pre-ANSI compiler, which semantics were chosen by gcc for the
"writable-strings" option, and for what reason?

The behaviors I know of in pre-ANSI compilers are (a) string literals
were put in writable storage, or (b) string literals were put in
non-writable storage (which might be RAM with memory management
protecting it). If a write was attempted to non-writable storage,
the behavior likely fell into two classes: (b1) the write was
ignored, or (b2) the write attempt caused some kind of CPU trap
which aborted the program or got mapped into a signal. Which of
(b1) or (b2) happened usually depended on hardware.

Even some compilers that did not implement non-writable-strings
could be compiled with a more complex (and system-specific) procedure
involving xstr which would preprocess the C and generate a big array
with the strings in it, and change the program to refer to that
array. That array was made read-only by, er, implementation-specific
magic.
 
C

Christopher Benson-Manica

Gordon Burditt said:
can make the number of implementations enormous. In this case,
both "writable-strings" and non-"writable-strings" can conform to
ANSI C.

But a program which relies on the behavior implied by the
"writable-strings" option is non-conforming.
 
C

CBFalconer

Christopher said:
But a program which relies on the behavior implied by the
"writable-strings" option is non-conforming.

The program doesn't rely on it. The option prevents creating some
non-conforming programs without having a warning.

--
"The mere formulation of a problem is far more often essential
than its solution, which may be merely a matter of mathematical
or experimental skill. To raise new questions, new possibilities,
to regard old problems from a new angle requires creative
imagination and and marks real advances in science."
-- Albert Einstein
 
K

Keith Thompson

CBFalconer said:
The program doesn't rely on it. The option prevents creating some
non-conforming programs without having a warning.

I think there's some confusion between two different options. gcc has
(had?) an option to make string literals writable, and another option
to warn about attempts to modify them.
 
G

Gordon Burditt

can make the number of implementations enormous. In this case,
True. But a compiler which works either way is still allowed. A
program which depends on either behavior to the exclusion of the
other is non-conforming.
The program doesn't rely on it. The option prevents creating some
non-conforming programs without having a warning.

I think this would be better stated as "the option prevents creating
some non-conforming programs without having a hard program crash
at runtime". If the compiler puts strings in write-protected memory
and write attempts cause program traps and aborts, that's what will
happen.

ANSI C doesn't define anything called a "warning", or make any
distinction between "warning" and "error".
 
C

Christopher Benson-Manica

True. But a compiler which works either way is still allowed. A
program which depends on either behavior to the exclusion of the
other is non-conforming.

Yes, although I'm having a difficult time imagining an otherwise
conforming program that relies on non-writable strings for its correct
operation, unless the correct operation of the program is to dump
core on attempting to modify a string literal.
 
G

Gordon Burditt

But a program which relies on the behavior implied by the
Yes, although I'm having a difficult time imagining an otherwise
conforming program that relies on non-writable strings for its correct
operation, unless the correct operation of the program is to dump
core on attempting to modify a string literal.

Ok, here's sort of an example, and it depends on more than just
non-writable-strings:

A compiler that makes strings non-writable is allowed to combine
them, so, that, for example, "hello" and "ello" have addresses that
are 1 byte apart, and two occurrences of the same string literal
in the same compilation unit are guaranteed (by this particular
implementation only) to have the same address. A program could
depend on that, using address comparison rather than strcmp() to
compare two string literals.

Ok, perhaps it's a lame example, but it doesn't require core dumps
as part of expected behavior. It does break rules about pointer
comparison for equality.
 

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

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top