[comp.std.c] Does ANSI insist this is legal?

rfg@paris.ics.uci.edu (Ronald Guilmette) (02/28/90)

Must a strictly conforming ANSI C implementation be able to generate an
executable program from the following?


	int main ();

	short s = (short) &main;
	char c = (char) &main;

	int main () { return 0; }

The above code makes SystemV assemblers croak and it makes BSD linkers croak.


// Ron Guilmette (rfg@ics.uci.edu)
// C++ Entomologist
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

gwyn@smoke.BRL.MIL (Doug Gwyn) (02/28/90)

In article <25EB8750.5286@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
>Must a strictly conforming ANSI C implementation be able to generate an
>executable program from the following?
>	int main ();
>	short s = (short) &main;
>	char c = (char) &main;

No -- a pointer is required to be interconvertable to some particular
implementation-defined integral type, not necessarily short or char.
Also note that the initializers violate the definition of a constant
expression and thus need not be supported by an implementation even if
short or char were the appropriate integer to hold a pointer value.

henry@utzoo.uucp (Henry Spencer) (03/01/90)

In article <25EB8750.5286@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
>Must a strictly conforming ANSI C implementation be able to generate an
>executable program from the following?
>
>	int main ();
>	short s = (short) &main;
>	char c = (char) &main;
>	int main () { return 0; }

Holy Scriptures, Oct 88 draft, verse 3.3.4:

	A pointer may be converted to an integral type.  The size of
	integer required and the result are implementation-defined.
	If the space provided is not long enough, the behavior is
	undefined.

Your program falls under the jurisdiction of that last sentence, since
it is vanishingly unlikely that a pointer will fit in a char and not too
likely nowadays that it will fit in a short.  So the compiler can remove
all your files, send rude mail to your boss, and dump core if it wants.
-- 
"The N in NFS stands for Not, |     Henry Spencer at U of Toronto Zoology
or Need, or perhaps Nightmare"| uunet!attcan!utzoo!henry henry@zoo.toronto.edu

rfg@ics.uci.edu (Ronald Guilmette) (03/01/90)

In article <1990Feb28.180914.27504@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>In article <25EB8750.5286@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
>>Must a strictly conforming ANSI C implementation be able to generate an
>>executable program from the following?
>>
>>	int main ();
>>	short s = (short) &main;
>>	char c = (char) &main;
>>	int main () { return 0; }
>
>Holy Scriptures, Oct 88 draft, verse 3.3.4:
>
>	A pointer may be converted to an integral type.  The size of
>	integer required and the result are implementation-defined.
>	If the space provided is not long enough, the behavior is
>	undefined.
>
>Your program falls under the jurisdiction of that last sentence, since
>it is vanishingly unlikely that a pointer will fit in a char and not too
>likely nowadays that it will fit in a short.  So the compiler can remove
>all your files, send rude mail to your boss, and dump core if it wants.

Well, this raises yet another question.

I agree that any attempt to use a space which is not long enough (to hold
the pointer value initializer) can (allowably, under the standard) cause you
to lose all your files, can cause your boss to receive rude mail, and can
cause a core dump, but the $64,000 question is "When may these catastrophies
occur?  At run-time or at compile-time?  Either?  Both?"

If the standard is trying to say that "the *run-time* behavior is undefined"
then that is one thing.  If it is trying to say that the compiler may (or can)
flag an error at compile time, that is an entirely different thing.

Right now, GCC accepts the above program without complaint (but I'm sure
that is the values of `s' or `c' were used, that run-time strangeness
would ensue).  The question is whether or not a standard conforming compiler
is *allowed* to "reject" the above code at compile time.


// Ron Guilmette (rfg@ics.uci.edu)
// C++ Entomologist
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

walter@hpclwjm.HP.COM (Walter Murray) (03/02/90)

Ronald Guilmette asks:

> Must a strictly conforming ANSI C implementation be able to generate an
> executable program from the following?


>	int main ();
>	short s = (short) &main;
>	char c = (char) &main;
>	int main () { return 0; }

No.  Setting aside the question of whether a pointer can fit in a char
or a short, this code violates Section 3.4:  "Cast operators in an
arithmetic constant expression shall only convert arithmetic types
to arithmetic types, except as part of an operand to the sizeof
operator."

Walter Murray
----------

walter@hpclwjm.HP.COM (Walter Murray) (03/02/90)

Ronald Guilmette writes:

> I agree that any attempt to use a space which is not long enough (to hold
> the pointer value initializer) can (allowably, under the standard) cause you
> to lose all your files, can cause your boss to receive rude mail, and can
> cause a core dump, but the $64,000 question is "When may these catastrophies
> occur?  At run-time or at compile-time?  Either?  Both?"

> If the standard is trying to say that "the *run-time* behavior is undefined"
> then that is one thing.  If it is trying to say that the compiler may (or can)
> flag an error at compile time, that is an entirely different thing.

I think this is an excellent question.  Simplifying the example:

   main (void)
   {
      char c; int i;
      c = (char)&j;
   }

Assuming a char can't hold a pointer, the behavior of this code is undefined.
May a conforming implementation produce an error at compile time?  I would
tend to say No.  Suppose the assignment were instead:

   c = 1 || (char)&j;

Presumably this is intended to be legal.  (See the last footnote in
Section 3.4.)  So there appear to be expressions that are legal,
like division by zero, AS LONG AS THE PROGRAM CONTROL FLOW IS SUCH
YOU DON'T TRY TO EVALUATE THEM.

Yet, according to the definition in 1.6, "undefined behavior" may
involve "terminating a translation".  An example might be using the
same identifier more than once as a label name in the same function.

The bottom line seems to be that it may not always be clear when
"undefined behavior" may include failing to translate.

Walter Murray
----------

henry@utzoo.uucp (Henry Spencer) (03/02/90)

In article <25EC428B.18849@paris.ics.uci.edu> rfg@ics.uci.edu (Ronald Guilmette) writes:
>>	If the space provided is not long enough, the behavior is
>>	undefined.
>>
>>Your program falls under the jurisdiction of that last sentence, since
>>it is vanishingly unlikely that a pointer will fit in a char and not too
>>likely nowadays that it will fit in a short.  So the compiler can remove
>>all your files, send rude mail to your boss, and dump core if it wants.
>
>I agree that any attempt to use a space which is not long enough (to hold
>the pointer value initializer) can (allowably, under the standard) cause you
>to lose all your files, can cause your boss to receive rude mail, and can
>cause a core dump, but the $64,000 question is "When may these catastrophies
>occur?  At run-time or at compile-time?  Either?  Both?"

"Undefined" really means "undefined".  Your text editor might send rude
mail to your boss when you type in that code (if your text editor is part
of your C implementation); the final report printed by your program might
contain the words "it's all lies, they're juggling the books".  Or anything
in between.  Or any combination of the above.

>Right now, GCC accepts the above program without complaint (but I'm sure
>that is the values of `s' or `c' were used, that run-time strangeness
>would ensue).  The question is whether or not a standard conforming compiler
>is *allowed* to "reject" the above code at compile time.

Yes.  Good compilers, in fact, will try to reject such things at compile
time rather than leaving run-time disasters lurking in wait for you.
(Alas, it is seldom possible to detect them at compile time in the general
case.)
-- 
MSDOS, abbrev:  Maybe SomeDay |     Henry Spencer at U of Toronto Zoology
an Operating System.          | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (03/03/90)

In article <12570048@hpclwjm.HP.COM> walter@hpclwjm.HP.COM (Walter Murray) writes:
>Assuming a char can't hold a pointer, the behavior of this code is undefined.
>May a conforming implementation produce an error at compile time?

You may recall that we had this debate several months ago, using a different
code example, with me on one side of the issue and most other X3J11 members
who participated in the discussion on the other.  I think it is an issue that
needs an official interpretation ruling.

roberto@ssd.csd.harris.com (Roberto Shironoshita) (03/05/90)

In article <25EC428B.18849@paris.ics.uci.edu> rfg@ics.uci.edu (Ronald Guilmette) writes:
> In article <1990Feb28.180914.27504@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
> >In article <25EB8750.5286@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
> >>Must a strictly conforming ANSI C implementation be able to generate an
> >>executable program from the following?
> >>
> >>	int main ();
> >>	short s = (short) &main;
> >>	char c = (char) &main;
> >>	int main () { return 0; }
> >
> >Holy Scriptures, Oct 88 draft, verse 3.3.4:
> >
> >	A pointer may be converted to an integral type.  The size of
> >	integer required and the result are implementation-defined.
> >	If the space provided is not long enough, the behavior is
> >	undefined.
> >
> >Your program falls under the jurisdiction of that last sentence, since
> >it is vanishingly unlikely that a pointer will fit in a char and not too
> >likely nowadays that it will fit in a short.  So the compiler can remove
> >all your files, send rude mail to your boss, and dump core if it wants.
>
> Well, this raises yet another question.
>
> I agree that any attempt to use a space which is not long enough (to hold
> the pointer value initializer) can (allowably, under the standard) cause you
> to lose all your files, can cause your boss to receive rude mail, and can
> cause a core dump, but the $64,000 question is "When may these catastrophies
> occur?  At run-time or at compile-time?  Either?  Both?"

Holy Scriptures, Dec. 88 draft, Chapter 1, verse 6:

	* Undefined behavior -- behavior, upon use of a
	  nonportable or erroneous program construct, of
	  erroneous data, or of indeterminately-valued objects,
	  for which the Standard imposes no requirements.
	  Permissible undefined behavior ranges from ignoring
	  the situation completely with unpredictable results,
	  to behaving during translation or program execution
	  in a documented manner characteristic of the
	  environment (with or without the issuance of a
	  diagnostic message), to terminating a translation or
	  execution (with the issuance of a diagnostic
	  message).

So the answer is "BOTH".  I'd like the $64,000 in small bills please ;-).

> If the standard is trying to say that "the *run-time* behavior is undefined"
> then that is one thing.  If it is trying to say that the compiler may (or
> can) flag an error at compile time, that is an entirely different thing.

It seems to me that the standard says there is nothing it can (or cares to)
say about the situation, and leaves it up to the implementors' good
judgement to do some sensible thing (I'm not sure if Henry's example of
undefined behavior qualifies as sensible ;-).  From the definition of
"undefined behavior" (now, that's a bit of standardese contradiction in
terms;-), it may be concluded that, as far as the standard is concerned,
both the compiler and the resultant executables form part of an
implementation, and the behavior of the implementation includes both the
compile-time and run-time behaviors.

> Right now, GCC accepts the above program without complaint (but I'm sure
> that is the values of `s' or `c' were used, that run-time strangeness
> would ensue).  The question is whether or not a standard conforming compiler
> is *allowed* to "reject" the above code at compile time.

As the quote says, the implementation is allowed to do pretty much anything
it pleases, which includes termination of translation with issuance of
diagnostic.
--
                               ||   Internet: shirono@ssd.csd.harris.com
     Roberto Shironoshita      ||
      Harris Corporation       ||             ...!novavax-\
   Computer Systems Division   ||   UUCP:                  -!hcx1!shirono
                               ||             ...!uunet---/
DISCLAIMER: The opinions expressed here are my own; they in no way reflect the
            opinion or policies of Harris Corporation.