Sean A.O. Harney
Sean A.O. Harney

Reputation: 24507

GCC #pragma to stop compilation

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

Answers (8)

Amaury MAILLÉ
Amaury MAILLÉ

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:

  • 6.10.5 Error directive, the behavior of #error is to "cause the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens."
  • 4 Conformance §4 "The implementation shall not successfully translate a preprocessing translation unit containing a #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

Aykhan Hagverdili
Aykhan Hagverdili

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

Dirk is no longer here
Dirk is no longer here

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

File stopthis.cpp

#include <iostream>

int main(void) {
  std::cout << "Hello, world\n";
  #ifndef GoOn
    #error I had enough
  #endif
  return 0;
}

Upvotes: 63

Klevh
Klevh

Reputation: 11

You can use:

#pragma GCC error "my message"

But it is not standard.

Upvotes: 0

mosh
mosh

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

Leo
Leo

Reputation: 827

#pragma GCC error "error message"

Ref: 7 Pragmas

Upvotes: 4

ideasman42
ideasman42

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

Michael
Michael

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

Related Questions