[comp.std.c] I can't find a good definition anywhere...

bph@buengc.BU.EDU (Blair P. Houghton) (05/10/89)

In article <FLEE.89May8171524@shire.cs.psu.edu> flee@shire.cs.psu.edu (Felix Lee) writes:
>Here's an extraordinarily silly idea for <default.h>.  Since the list
>
>Now, being able to say something like #pragma dumpdefines at an
>arbitrary point would be interesting.

Here's an extraordinarily neophytic question:

	What does a #pragma _do_, anyway?

Tain't the C (nor CPP) I'm used to.

				--Blair
				  "Back in the 20's, when I had
				   to walk to school four--no, FIVE--
				   miles in the snow, and the only
				   keywords in C were 'if' and 'struct'..."

karl@haddock.ima.isc.com (Karl Heuer) (05/10/89)

(Followups to comp.std.c; this is not a unix question.)

This guy walks into a bar with 500 #pragma's.  In article <2810@buengc.BU.EDU>
the bartender says,
>What does a #pragma _do_, anyway?

So the guy says, "Anything it wants!"
(With apologies to any 500# gorillas in the audience.)

Seriously, though, #pragma is the universal escape to allow implementors to
do the sorts of things that they just *have* to add to the language (e.g.
`#module' or `#ident'), in such a way that it won't interfere with other ANSI-
conforming implementations.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
(Oh, wow!  I actually used `#' as a pound sign!)

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/12/89)

In article <13022@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes:
>>What does a #pragma _do_, anyway?
>So the guy says, "Anything it wants!"

There is some sentiment that whatever #pragma does, the rest of the
specifications in the Standard still have to be conformed to, so it's
not quite "anything".  Valid examples are output listing control,
levels of optimization, etc.

henry@utzoo.uucp (Henry Spencer) (05/12/89)

In article <10253@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>>>What does a #pragma _do_, anyway?
>>So the guy says, "Anything it wants!"
>
>There is some sentiment that whatever #pragma does, the rest of the
>specifications in the Standard still have to be conformed to, so it's
>not quite "anything".  Valid examples are output listing control,
>levels of optimization, etc.

Unfortunately, while there is some sentiment for this view, it's not
guaranteed by the Standard (unless the relevant text has changed since
the October draft), so it should not be relied on.  There are two
possible interpretations of the actual wording, neither of which is
internally contradictory:  either #pragma is allowed to change the
rules, or it isn't.  Opinions vary on which interpretation is preferable,
but the Standard doesn't say.
-- 
Mars in 1980s:  USSR, 2 tries, |     Henry Spencer at U of Toronto Zoology
2 failures; USA, 0 tries.      | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

tneff@bfmny0.UUCP (Tom Neff) (05/13/89)

In article <1989May12.154810.21589@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>In article <10253@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>>There is some sentiment that whatever #pragma does, the rest of the
>>specifications in the Standard still have to be conformed to, so it's
					^^^^^^^^^^^^^^^^^^^^^
					That is, in order for
					the resulting program
					to remain ANSI conformant...
>>not quite "anything".  Valid examples are output listing control,
>>levels of optimization, etc.
>
>Unfortunately, while there is some sentiment for this view, it's not
>guaranteed by the Standard (unless the relevant text has changed since
>the October draft), so it should not be relied on.  There are two
>possible interpretations of the actual wording, neither of which is
>internally contradictory:  either #pragma is allowed to change the
>rules, or it isn't.  Opinions vary on which interpretation is preferable,
>but the Standard doesn't say.

I don't think there's any doubt whatsoever that #pragma cannot be used
to "change the rules" in the sense that saying something like

	#pragma operator_precedence(+/*-.[]->)

would yield a *valid ANSI C* program whose operator precedence differed
radically from the Standard.  My reading of the draft suggests that you
are allowed to put anything you want in a #pragma and still have a
valid ANSI C program *so long as the rest of the source would be valid
ANSI C anyway.*  That's why output listing control and optimization are
the "friendliest" examples.  Less friendly are things like

	#pragma allow_our_weird_extended_keywords=YES

which then allows statements like

	extern void massively_parallel testfunc(int a);

or

	shared char *mydata;

to compile. Implementors are certainly going to do this, since #pragma 
is a very natural facility for it. (I think MS already does to some 
extent.) The question is, is the resulting *program* ANSI C? Not at 
all -- #pragma was used to break conformance. It'll be a rare 
implementation where this isn't possible one way or another, if only 
because every compiler has predecessors from the same vendor who will 
want a safety valve for backward compatibility. Is a compiler that's 
*capable* of compiling a non-conformant program via #pragma, but is 
also capable of compiling conformantly otherwise, still allowed to 
define _STDC_ 1? Yes! if the killer #pragma isn't in effect. I think 
this is what Henry's really asking. 
-- 
Tom Neff				UUCP:     ...!uunet!bfmny0!tneff
    "Truisms aren't everything."	Internet: tneff@bfmny0.UU.NET

henry@utzoo.uucp (Henry Spencer) (05/14/89)

In article <14324@bfmny0.UUCP> tneff@bfmny0.UUCP (Tom Neff) writes:
>>... There are two
>>possible interpretations of the actual wording, neither of which is
>>internally contradictory:  either #pragma is allowed to change the
>>rules, or it isn't...
>
>I don't think there's any doubt whatsoever that #pragma cannot be used
>to "change the rules" in the sense that saying something like
>
>	#pragma operator_precedence(+/*-.[]->)
>
>would yield a *valid ANSI C* program whose operator precedence differed
>radically from the Standard.  My reading of the draft suggests that you
>are allowed to put anything you want in a #pragma and still have a
>valid ANSI C program *so long as the rest of the source would be valid
>ANSI C anyway.*

Can you justify this with chapter and verse?  No other construct follows
such a rule; a partial program is often not a legal program.

It *is* true that you must read the whole standard, not an isolated part
of it, to get the correct meaning.  Unfortunately, the whole standard
includes that marvellous line about how #pragma has "implementation-defined
effects", so you cannot understand the meaning of (say) the section on
the "for" statement without considering that a #pragma might have an
implementation-defined effect on it.

The definition of "implementation-defined" does plausibly imply that the
program should be legal without the #pragma, but I wouldn't call the
issue clear-cut.  And nothing says that the semantics have to be the same.
Your precedence example isn't a good one.  Changing the operator precedence
will not usually make a program illegal, unless type-compatibility issues
intervene.  It just changes the meaning.

In practice, all bets are off when a #pragma appears.
-- 
Mars in 1980s:  USSR, 2 tries, |     Henry Spencer at U of Toronto Zoology
2 failures; USA, 0 tries.      | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/14/89)

In article <14324@bfmny0.UUCP>, tneff@bfmny0.UUCP (Tom Neff) writes:
- >In article <10253@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
- >>There is some sentiment that whatever #pragma does, the rest of the
- >>specifications in the Standard still have to be conformed to, so it's
- 					^^^^^^^^^^^^^^^^^^^^^
- 					That is, in order for
- 					the resulting program
- 					to remain ANSI conformant...
- >>not quite "anything".

No!  It is the implementation that I was saying is required to conform
to the specifications of the Standard whether or not a program contains
any particular construct (including #pragma).  #pragma is not license
for the implementation to suddenly ignore the constraints of the Standard.

tneff@bfmny0.UUCP (Tom Neff) (05/14/89)

In article <10257@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
>No!  It is the implementation that I was saying is required to conform
>to the specifications of the Standard whether or not a program contains
>any particular construct (including #pragma).  #pragma is not license
>for the implementation to suddenly ignore the constraints of the Standard.

Then there will be no conformant implementations and Doug's interpretation
will be vacuously correct.  Every implementation I have encountered where
#pragma is supported has at least one way you can use it to do something
non-ANSI.  Is this likely to reverse itself?  Compilers have to live in
the real world, including the grungy goal of backward compatibility.

-- 
Tom Neff				UUCP:     ...!uunet!bfmny0!tneff
    "Truisms aren't everything."	Internet: tneff@bfmny0.UU.NET

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/14/89)

In article <1989May12.154810.21589@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes:
> In article <10253@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
> >There is some sentiment that whatever #pragma does, the rest of the
> >specifications in the Standard still have to be conformed to, so it's
> >not quite "anything".
> Unfortunately, while there is some sentiment for this view, it's not
> guaranteed by the Standard (unless the relevant text has changed since
> the October draft), so it should not be relied on.

In the second formal public review, X3J11 responded to an issue summarized
as "May #pragma alter the I/O behavior of a strictly conforming program?"
with the following:

	It is true that according to a *literal* reading of Section 1.7,
	a *strictly conforming program* could not safely contain #pragma,
	because the effect of #pragma is entirely *implementation defined*
	according to Section 3.8.6, and that certainly could include
	affecting the I/O behavior.  However, that is not the intent of
	#pragma, because the "requirements" in Section 3.8.6 are not the
	whole story -- the requirements imposed by the rest of the
	Standard must be met as well, and these sufficiently limit the
	effect that a #pragma can have.

	Given the confusion over this, to be safe you should probably
	avoid using #pragma in strictly conforming programs.  (Besides,
	some implementation may choose to interpret another's benign
	#pragma as, for example, a request to call you in the middle of
	the night to let you know when your program is being compiled,
	and you may find that an unpleasant surprise.)

I would hope that in the "interpretations phase" of X3J11 existence, it
will reaffirm this position.  The other interpretation (that #pragma
exempts an implementation from conforming to the specifications) would be
folly, because the same reasoning could be applied to other instances of
implementation-defined behavior, making a farce of the whole notion.

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/14/89)

In article <14327@bfmny0.UUCP> tneff@bfmny0.UUCP (Tom Neff) writes:
>Every implementation I have encountered where #pragma is supported has at
>least one way you can use it to do something non-ANSI.

You don't need #pragma for your code to be non-conformant.
The important thing is that *conformant* code following the
occurrence of #pragma be interpreted by the implementation
according to the ANSI specs.

tneff@bfmny0.UUCP (Tom Neff) (05/14/89)

In article <10260@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>You don't need #pragma for your code to be non-conformant.
>The important thing is that *conformant* code following the
>occurrence of #pragma be interpreted by the implementation
>according to the ANSI specs.

That is *exactly* what I said two articles ago, and Doug objected.
If your *code* would be ANSI without the #pragma, then no worries.
The tough question, which I thought (think? thunk?) Henry was getting
at, is whether a *compiler* that allows you to use #pragma to create
non-conformant code -- even though it satisifies the other requirements
above -- deserves the ANSI imprimatur.  My position is that there's
no choice, because they'll all be doing it.
-- 
Tom Neff				UUCP:     ...!uunet!bfmny0!tneff
    "Truisms aren't everything."	Internet: tneff@bfmny0.UU.NET

diamond@diamond.csl.sony.junet (Norman Diamond) (05/15/89)

OK, most compilers will have #pragmas that can provide a non-ANSI
interpretation of a program that looks like a strictly conformant
program.  Any compiler that claims ANSI conformance will have to be
capable of ignoring such #pragmas, perhaps in a mode that is set by
using flag -~P (no pragma).  Bet there's only one person on the net
who would use that flag ;-).

Of course, such a flag isn't implemented yet, so here's a workaround:

.c.o:
	sed -e "/^[ 	]*#[ 	]*pragma/d" < $*.c | $(CC) $(CFLAGS) -c -o $@

--
Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.co.jp@relay.cs.net)
  The above opinions are my own.   |  Why are programmers criticized for
  If they're also your opinions,   |  re-implementing the wheel, when car
  you're infringing my copyright.  |  manufacturers are praised for it?

peter@ficc.uu.net (Peter da Silva) (05/15/89)

How about some examples of what you think are valid pragmas? What do you think
of:

#pragma model(large)
#pragma interface(plm/386,dq$delete)
#pragma segment(code,romcode)
#pragma asm(mov %fp(2),%fr0)
#pragma noalias(main.argv)
#pragma byteorder(bigendian)
#pragma generate(80386)
#pragma enable(pascal_strings)
#pragma ada(FUNCTION WHATEVER IS...)
#pragma flags(-I/usr/X/include -L/usr/X/lib)
#pragma enable(gcc_expressions)
#pragma inline(getchar,putchar,strcmp,strcpy,strlen)
#pragma list(full)
#pragma import(getchar from romlib.iolib,putchar from romlib.iolib)
#pragma rename(strlen,Strlen)
#pragma list(dumpmacros)
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.

Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.
Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/16/89)

In article <4190@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>#pragma model(large)
>#pragma segment(code,romcode)
>#pragma byteorder(bigendian)
>#pragma generate(80386)
>#pragma flags(-I/usr/X/include -L/usr/X/lib)
>#pragma list(full)
>#pragma import(getchar from romlib.iolib,putchar from romlib.iolib)
>#pragma list(dumpmacros)

I think all the above would be valid use of #pragma.

>#pragma inline(getchar,putchar,strcmp,strcpy,strlen)
>#pragma rename(strlen,Strlen)

These two would probably be valid, depending on how the details are handled.

>#pragma interface(plm/386,dq$delete)
>#pragma ada(FUNCTION WHATEVER IS...)

I don't know what these mean.

>#pragma noalias(main.argv)
>#pragma enable(gcc_expressions)

To the extent that strictly conforming code may have its behavior altered
by these, I don't think they're valid.

>#pragma asm(mov %fp(2),%fr0)
>#pragma enable(pascal_strings)

These seem to cause readily detectable alteration of semantics and thus
would not be valid.

diamond@diamond.csl.sony.junet (Norman Diamond) (05/16/89)

In article <4190@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:

>What do you think of:

>#pragma model(large)
IMHO I could live with this, though I'd rather see an option that is
settable in a pull-down menu (or flag on the command line, etc.).

>#pragma interface(plm/386,dq$delete)
This seems reasonable.

>#pragma segment(code,romcode)
This seems reasonable too.

>#pragma asm(mov %fp(2),%fr0)
I can think of lots of strictly conformant programs that will crash or
do various other obscure things when this pragma is added.  This is
exactly the kind of thing that should not be a pragma.  It was better
when asm() was simply a pseudo-function.  Or an #asm directive would
be better too.  This kind of effect deviates farther from the allowed
meanings of #pragma than anything else I can think of.

>#pragma noalias(main.argv)
Well, if this tells the truth when it is added to a strictly conformant
program, then it will not change the behavior of the program.  If it
tells a lie, then a strictly conformant program (which does alias that)
will be broken by the lie.  Technically this #pragma should not be
allowed, but IMHO I would allow it and let liars get what they ask for.

>#pragma byteorder(bigendian)
>#pragma generate(80386)
>#pragma enable(pascal_strings)
Same opinion as for model.

>#pragma ada(FUNCTION WHATEVER IS...)
Same opinion as for interface.

>#pragma flags(-I/usr/X/include -L/usr/X/lib)
MHO is obvious....

>#pragma enable(gcc_expressions)
This one would only be used in a non-conformant program, eh?  Anyway,
it would not change the meaning of a strictly conformant program, so
it seems fine to me.

>#pragma inline(getchar,putchar,strcmp,strcpy,strlen)
A strictly conformant program would not redefine these identifiers
anyway.  They would have to be the ones with the standard meanings,
so a compiler would already know if it's capable of inlining them.
Nonetheless this is in the spirit of #pragma, so I would allow it
even though it will usually be a no-op.  (I could imagine a #pragma
to *prevent* inlining though, to assist with debugging.)

>#pragma list(full)
Perfect.

>#pragma import(getchar from romlib.iolib,putchar from romlib.iolib)
Well, if you have a non-conformant program that wants to use these
functions without doing an #include [<"]stdio.h[>"], then this might
be a way to give meaning to a program that otherwise had no meaning.
If a strictly conformant program does include stdio.h, then this
pragma had better not change the meaning of the program.

>#pragma rename(strlen,Strlen)
IMHO #define Strlen strlen would be better for this.  Again it is hard
to see how a strictly conformant program could use this one.

>#pragma list(dumpmacros)
Also perfect.  Hmm, er... better than perfect.

--
Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.co.jp@relay.cs.net)
  The above opinions are my own.   |  Why are programmers criticized for
  If they're also your opinions,   |  re-implementing the wheel, when car
  you're infringing my copyright.  |  manufacturers are praised for it?

peter@ficc.uu.net (Peter da Silva) (05/16/89)

In article <10267@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
> In article <4190@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
> >#pragma interface(plm/386,dq$delete)
> >#pragma ada(FUNCTION WHATEVER IS...)

> I don't know what these mean.

Different ways of saying 'this function is to be called with the calling
convention of this language'. The former is based on the INTERFACE() argument
to the intel PL/M compiler.
-- 
Peter da Silva, Xenix Support, Ferranti International Controls Corporation.

Business: uunet.uu.net!ficc!peter, peter@ficc.uu.net, +1 713 274 5180.
Personal: ...!texbell!sugar!peter, peter@sugar.hackercorp.com.

tneff@bfmny0.UUCP (Tom Neff) (05/17/89)

Here are the #pragma's you can use with Intel's iC-86 (-286, -386).

	#pragma align [(["structure-tag"[=size]][,...])]
		noalign [("structure-tag"[,...])]

	#pragma [no]code		<-- assembly type listing

	#pragma compact			<-- memory model

	#pragma [no]cond		<-- list conditional code

	#pragma [no]debug		<-- symbol info in object module

	#pragma [no]extend		<-- allows keywords "alien,"
					    "far," "near," and "readonly,"
					    and ignores "$" in identifiers.

	#pragma fixedparams [("function"[,...])]
					<-- specifies calling convention

	#pragma interrupt("ifunction"[=n][,...])
					<-- identifies interrupt handlers

	#pragma large			<-- memory model

	#pragma [no]list

	#pragma [no]listinclude

	#pragma medium			<-- memory model

	#pragma mod[1]86		<-- instruction set

	#pragma object[(pathname)]
		noobject

	#pragma optimize(0|1|2|3)

	#pragma pagelength(n)

	#pragma pagewidth(n)

	#pragma preprint [(pathname)]	<-- preprocessor output
		nopreprint

	#pragma print[(pathname)]
		noprint

	#pragma ram			<-- which segment constants go in
		rom

	#pragma searchinclude("directory"[,...])]
		nosearchinclude

	#pragma small			<-- memory model

	#pragma [no]symbols		<-- symbol table in listing

	#pragma tabwidth(width)		<-- in listing

	#pragma title[("string")

	#pragma [no]type		<-- type info in object

	#pragma varparams[("function"[,...])]
					<-- calling convention

These pragmas may be mixed freely on a line.  The compiler defines
_STDC_ = 1.

	#pragma [no]xref		<-- in listing







-- 
Tom Neff				UUCP:     ...!uunet!bfmny0!tneff
    "Truisms aren't everything."	Internet: tneff@bfmny0.UU.NET