How come clang and gcc don't produce a cast warning for this openssl macro, but do otherwise?

58 views Asked by At

Consider compiling the following code with -Wold-style-cast

#include <openssl/evp.h>

extern "C" {
#define TEST (int)123
}

long BIO_ctrl(int bp, int cmd, long larg, void *parg); // added for the example to compile minimally.

int main() { 
    auto example = BIO_pending(123);
    return TEST; 
}

https://godbolt.org/z/Mdodc58z7

If we call the file foo.cpp and compile with g++ foo.cpp -Wold-style-cast -Werror it fails with a warning with the following output:

foo.cpp:4:19: error: use of old-style cast to ‘int’ [-Werror=old-style-cast]
    4 | #define TEST (int)123
      |                   ^~~
foo.cpp:11:12: note: in expansion of macro ‘TEST’
   11 |     return TEST;
      |            ^~~~
cc1plus: all warnings being treated as errors

It also fails on clang.

How come we only receive the warning for the use of TEST but not BIO_pending when they both use old style casts?

Note that the openssl macro is defined as follows:

# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)

I thought maybe it being defined within an extern "C" block had something to do with it but evidently not.

Note that removing the use of TEST means compilation succeeds. Also placing the definition of BIO_pending into foo.cpp results in the warning being raised. Do openssl and such headers somehow have exceptions built in for these warnings?

I discovered this when I noticed a build using distcc failing to complete remotely but compiling locally. Distcc expands the macros locally before compiling remotely so the movement of the macro out of the header is causing the warning to be picked up and compilation to fail.

0

There are 0 answers