[comp.lang.c] Behavior of #error preprocessor directive

jtc@van-bc.wimsey.bc.ca (J.T. Conklin) (01/08/91)

Is use of the #error preprocessor directive required (or permitted) to
halt compilation of a source module.  I don't have a copy of the C
standard, and K&R2 says nothing much more than the token sequence
following the directive will be printed.

I ask this because I believe both behaviors (halting or continuing)
are useful.  But it would be even more useful if both mechanisms were
available separately.


For example, I currently use #error to halt compilation whenever
compile-time consistency checks fail; but it would be useful to use
a #warning directive for cases like this:

    #ifdef M_XENIX
    #warning Use work around for bug brain dead SCO/Microsoft C compiler
	.....
    #else
	.....
    #endif

If the text of the #warning was printed during compilation, it would
remind me that I could remove the work around whenever SCO releases a
fixed version of their compiler (Granted, that is extremely unlikely :-).


I've seen a lot of code with little workarounds that still remain
years after the original bug that made the workaround necessary has be
squashed.  Responsibility for maintaining a piece of software may 
change hands many times during its life.  Proper use of such #warnings
might help reduce the burden of software maintenance.

Has anyone experimented with user-introduced warning messages in C? In
any other language?  Do they work, or do programmers neglect to use
them?  Is there a real need for such a feature?


In any case, was anything like my #warning directive discussed during
the standardization process?  If this turns out to be a good idea,
there should be plenty of time to slice it into compilers and get some
feel of weather its really worthwhile.  When does the standard get
reviewed again anyway? '95? '00?

	--jtc


-- 
J.T. Conklin	jtc@wimsey.bc.ca, ...!{uunet,ubc-cs}!van-bc!jtc

henry@zoo.toronto.edu (Henry Spencer) (01/08/91)

In article <1192@van-bc.wimsey.bc.ca> jtc@van-bc.wimsey.bc.ca (J.T. Conklin) writes:
>Is use of the #error preprocessor directive required (or permitted) to
>halt compilation of a source module...

Permitted but not required.  The whole area of response to errors is outside
the scope (as eventually decided) of the standard.  It is legitimate to
write a C implementation which crashes your machine as soon as any error
message is produced, although you may have trouble convincing anyone to
buy it...
-- 
If the Space Shuttle was the answer,   | Henry Spencer at U of Toronto Zoology
what was the question?                 |  henry@zoo.toronto.edu   utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (01/09/91)

In article <1192@van-bc.wimsey.bc.ca> jtc@van-bc.wimsey.bc.ca (J.T. Conklin) writes:
>Is use of the #error preprocessor directive required (or permitted) to
>halt compilation of a source module.

#error produces a diagnostic message, nothing more.

>In any case, was anything like my #warning directive discussed during
>the standardization process?

Yes.  We spelled it #error, though.

Note that code intended to be compiled (with appropriate conditionalizing)
by both ANSI and pre-ANSI compilers should not use #error, because many
pre-ANSI C preprocessors would terminate fatally upon seeing #error, even
in #ifed-out source code.  Thus I tend to still use the kludge
	#if SOME_EXPR
	#include "*** ERROR -- SOME_EXPR ***"
	#endif
which has a more drastic effect than #error anyway.

scs@adam.mit.edu (Steve Summit) (01/10/91)

In article <1192@van-bc.wimsey.bc.ca> jtc@van-bc.wimsey.bc.ca (J.T. Conklin) writes:
>Is use of the #error preprocessor directive required (or permitted) to
>halt compilation of a source module.
>I ask this because I believe both behaviors (halting or continuing)
>are useful.  But it would be even more useful if both mechanisms were
>available separately.

I agree wholeheartedly.  If I had to choose just one, I'd prefer
print-error-and-continue, which is what Henry and Doug have
implied #error really is, but read on.

In article <1991Jan8.011940.26586@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>Permitted but not required.  The whole area of response to errors is outside
>the scope (as eventually decided) of the standard.

The relevant section is 3.8.5, which states simply that #error
"causes the implementation to produce a diagnostic message that
includes" the user's message text.  However, the Rationale
asserts that "It is the intent of the Committee... that
translation cease immediately upon encountering this directive,
if this is feasible in the implementation; further diagnostics on
text beyond the directive are apt to be of little value."

Assuming, then, that implementors follow the Rationale as well as
the Standard, programmers can't assume that translation will
continue after an #error.

In article <14792@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In article <1192@van-bc.wimsey.bc.ca> jtc@van-bc.wimsey.bc.ca (J.T. Conklin) writes:
>>In any case, was anything like my #warning directive discussed during
>>the standardization process?
>
>Yes.  We spelled it #error, though.

The Rationale disagrees.  (I'm not arguing with Doug; I'd prefer
his interpretation.  The "intent of the Committee" as stated in
Rationale section 3.8.5 is nowhere else evident, and refers
either to language in an earlier Draft which has since been
deleted, or to unpublished X3J11 discussions which the
Rationale's author is relaying to us.)  As it stands, #error is
most likely to be interpreted by a compiler as fatal, and useful
print-error-message-and-continue functionality is truly missing.

This is where #pragma gets handy.  #pragma is specifically the
escape hatch for all sorts of useful creeping featureism; I would
propose

	#pragma warning pp-tokens
	                         opt

for any implementor who wishes to provide a print-error-message-
and-continue extension.  (Unfortunately, #pragma warning" is also
a likely choice for a warning level switch.)  Note that this is a
"nice" #pragma: it doesn't affect the interpretation of the rest
of the source code (i.e. it doesn't change the language accepted,
which is something that debate on comp.std.c frequently suggests
#pragma should not do).

(Actually, if I got to choose two features, I'd probably pick
print-message-and-continue and abort-compilation; it seems more
orthogonal to have user-requested compilation abortion separated
from user-requested error message printing.)

If anyone is wondering what the fuss is about, it's just an
extension of the notion that useful compilers process as much of
a source file as they can, even in the presence of errors, rather
than aborting on the very first error.  It's true that some of
the conditions under which programmers would make use of #error
would best be fatal, but I suspect (unproven assertion) that the
majority would not be so fatal that all further compilation would
be pointless.

One final point: Doug continues:
>Note that code intended to be compiled (with appropriate conditionalizing)
>by both ANSI and pre-ANSI compilers should not use #error, because many
>pre-ANSI C preprocessors would terminate fatally upon seeing #error, even
>in #ifed-out source code.  Thus I tend to still use the kludge
>	#if SOME_EXPR
>	#include "*** ERROR -- SOME_EXPR ***"
>	#endif
>which has a more drastic effect than #error anyway.

Here is another useful kludge, though less portable.  (I'm sure
Doug has seen it; others may not have.)

	#if SOME_EXPR
	 #error SOME_EXPR
	#endif

(There's a space before #error.)  "Most" pre-ANSI compilers
(where "most" is of course defined as "all the ones *I've* ever
used :-) ) can't deal with spaces before #directives, and choke
unless they're #ifdeffed out, in which case they don't care.  The
disadvantage is that they don't generally choke with the message
you've specified.  The advantage is that you do get an honest-to-
goodness #error on an ANSI compiler.

                                            Steve Summit
                                            scs@adam.mit.edu

gordon@sneaky.UUCP (Gordon Burditt) (01/12/91)

>Note that code intended to be compiled (with appropriate conditionalizing)
>by both ANSI and pre-ANSI compilers should not use #error, because many
>pre-ANSI C preprocessors would terminate fatally upon seeing #error, even
>in #ifed-out source code.  Thus I tend to still use the kludge
>	#if SOME_EXPR
>	#include "*** ERROR -- SOME_EXPR ***"
>	#endif
>which has a more drastic effect than #error anyway.

This is one place where trigraphs can be useful:

#if SOME_EXPR
??=error "*** ERROR -- SOME_EXPR ***"
#endif /* SOME_EXPR */

If it's an ANSI compiler, it recognizes the second line as #error.
If it's not an ANSI compiler, it probably doesn't recognize ??= as a
trigraph, and will call it an error instead.

						Gordon L. Burditt
						sneaky.lonestar.org!gordon

bright@nazgul.UUCP (Walter Bright) (01/14/91)

In article <1192@van-bc.wimsey.bc.ca> jtc@van-bc.wimsey.bc.ca (J.T. Conklin) writes:
/Has anyone experimented with user-introduced warning messages in C? In
/any other language?  Do they work, or do programmers neglect to use
/them?  Is there a real need for such a feature?

Zortech C used to have #message and #exit pragmas, which would cause a
message to be printed during compilation and the compiler to terminate
compilation, respectively. I suggested them to the ANSI C committee, who
rejected the idea. The features were eventually removed due to complaints
about them not being ANSI C. No one complained about them being removed,
which I took to mean no one used them ...