Reputation: 24507
Is there a GCC pragma directive that will stop, halt, or abort the compilation process?
I am using GCC 4.1, but I would want the pragma to be available in GCC 3.x versions also.
Upvotes: 44
Views: 51133
Reputation: 21
As some people have pointed out, without ever explaining why, #error
does not halt compilation immediately. I think the why warrants some explanation.
If we refer to this draft of C11, we can see the following:
#error
is to "cause the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens."#error
processing directive unless it is part of a group skipped by conditional inclusion".The actual implementation of #error
is therefore compiler dependent. What must be done for the implementation to be conformant is to generate a diagnostic message and not successfully translate the translation unit. GCC does both, so its implementation of #error
is conformant.
Whether the implementation stops compilation immediately is unspecified by the standard.
If we look at gcc, we can compile the following file, error.c
:
#error Error
void f(int a) {
*a = 12;
}
With the standard compilation line
$ gcc -c error.c -o /dev/null
error.c:1:2: error: #error Error
1 | #error Error
| ^~~~~
error.c: In function ‘f’:
error.c:4:3: error: invalid type argument of unary ‘*’ (have ‘int’)
4 | *a = 12;
| ^~
GCC emits two errors, including one after the #error
. Obivously, gcc did not immediately stop compilation. This answer by mosh gives a workaround to immediately halt compilation: including a non existent header. This is considered a fatal error (as pointed out in this answer), and gcc will immediately halt compilation upon hitting a fatal error. The error generated by #error
is not fatal, thus gcc is allowed to continue processing the input in whatever way it wants.
To turn #error
into an instant compilation stop we can, following that same answer, simply add -Wfatal-errors
to the command line to have gcc stop as soon as it hits any kind of error.
$ gcc -c error.c -Wfatal-errors -o /dev/null
error.c:1:2: error: #error Error
1 | #error Error
| ^~~~~
compilation terminated due to -Wfatal-errors.
Note that -Wfatal-errors
is only available from GCC 4.x onwards. For GCC 3.x and prior, mosh's solution that includes a non existent header remains the best. In general, mosh's solution neatly addresses the problem: it works on all versions of GCC and does not turn every error into an instant stop.
Upvotes: 2
Reputation: 29985
An alternative is to use static_assert
:
#if defined(_MSC_VER) && _MSC_VER < 1916
static_assert(false, "MSVC supported versions are 1916 and later");
#endif
Upvotes: 0
Reputation: 368439
You probably want #error
:
$ cd /tmp
$ g++ -Wall -DGoOn -o stopthis stopthis.cpp
$ ./stopthis
Hello, world
$ g++ -Wall -o stopthis stopthis.cpp
stopthis.cpp:7:6: error: #error I had enough
#include <iostream>
int main(void) {
std::cout << "Hello, world\n";
#ifndef GoOn
#error I had enough
#endif
return 0;
}
Upvotes: 63
Reputation: 1528
This works:
#include <stophere>
GCC stops when it can't find the include file. I wanted GCC to stop if C++14 was not supported.
#if __cplusplus<201300L
#error need g++14
#include <stophere>
#endif
Upvotes: 15
Reputation: 48178
While typically #error
is sufficient (and portable), there are times when you want to use a pragma
, namely, when you want to optionally cause an error within a macro.
Here is an example use which depends on C11's _Generic
and _Pragma
.
This example ensures var
isn't an int *
or a short *
, but not a const int *
at compile time.
Example:
#define MACRO(var) do { \
(void)_Generic(var, \
int *: 0, \
short *: 0, \
const int *: 0 _Pragma("GCC error \"const not allowed\"")); \
\
MACRO_BODY(var); \
} while (0)
Upvotes: 7
Reputation: 55435
I do not know about a #pragma
, but #error
should do what you want:
#error Failing compilation
It will terminate compilation with the error message "Failing compilation".
Upvotes: 23