<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/70025>70025</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[C Standard] Has it been considered to make #if defined() operator in macro not Undefined Behavior?
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
juj
</td>
</tr>
</table>
<pre>
Consider
`a.c`
```c++
#define HAS_SIMD (defined(__SSE__) || defined(__ARM_NEON__))
#if HAS_SIMD
// ...
#endif
```
While the above seems a "perfectly logical" piece of code, still building this code will emit the warnings
```
a.c:3:5: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
3 | #if HAS_SIMD
| ^
a.c:1:19: note: expanded from macro 'HAS_SIMD'
1 | #define HAS_SIMD (defined(__SSE__) || defined(__ARM_NEON__))
| ^
a.c:3:5: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
a.c:1:39: note: expanded from macro 'HAS_SIMD'
1 | #define HAS_SIMD (defined(__SSE__) || defined(__ARM_NEON__))
| ^
2 warnings generated.
```
which is as per documented in GCC manual: https://gcc.gnu.org/onlinedocs/cpp/Defined.html
```
If the defined operator appears as a result of a macro expansion, the C standard says the behavior is undefined.
GNU cpp treats it as a genuine defined operator and evaluates it normally. It will warn wherever your code uses
this feature if you use the command-line option -Wpedantic, since other compilers may handle it differently. The
warning is also enabled by -Wextra, and can also be enabled individually with -Wexpansion-to-defined.
```
But.. This seems like a case of Undefined Behavior where the standard could "just" well-define the operator to work, without any downside?
In other words, there does not seem to exist any rationale why the above behavior should fundamentally be Undefined Behavior, and why it could not be well-specified (maybe in a newer version of the C standard?)
Or I wonder if I have missed some scenario of why speccing that would be fundamentally unfeasible?
I understand this is a C language standard question rather than an LLVM implementation question. I was browsing https://www.open-std.org/jtc1/sc22/wg14/www/contributing.html to figure out how I could direct such a question to the people at the C language committee, but it was not easy to find a good avenue, so I thought to inquire about this here, presumably some of the LLVM devs are also part of the standards committees.
It would be good to understand why this particular behavior could not be well-defined if there is an obstruction? Couldn't the `"GNU cpp treats it as a genuine defined operator and evaluates it normally."` part be hoisted up into the C standard? People sometimes complain about C/C++ languages being bad due to UB, so having this type of UB when there is no "benefit" would certainly not be helping the case.
(I understand there are ways to refactor the above code to avoid the warning, that's beside the point)
--------
Related, I tried to find information to understand what guarantees passing `-Wno-expansion-to-defined` in Clang would give? It will hide the warning, but is there documentation as to how it will behave in Clang? I.e. will it be guaranteed to "work" as one expects?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUV01v4zgS_TXMpWDBpuI4OfiQOO2ZANM9i-nt7WNQEksW0xSp4Yc1_veLomTFSWf3NMBiA6fTlqjiq_eqHksYgj5Yoq1YP4j14xWm2Dq_fUkvV5VTp-3O2aAVebF8FMt7cbPEohY3y_nr-KmFfODPeFWWihptCX69__r89enzIwh5O15SQt4-P3_9-un5Wcg7EJud2Ozg8t79H5-fv3z6_UtewJ8x5jmybuao52t7IfdQFMW8hqzSzTuE49fvrTYEsSXAyh0JAlEXAEFI2ZNvqI7mBMYddI1GSAm9pprANVA7RULuIERtDFRJG6XtAWKrQ74HA1-nTsccfUBvtT2ED0Ewg-V9Kcr7tSjvz2v5vx3W3gH91aMN2lnovVOp5o2E3MwkbaDFAMlOF6CiFo_aeRDrh8X3-elFdIvzM-uJLACAklmHj6iE_JPvrj9dYl3x7x0jtC4S_827KFLQeNdNuIXczPHk5jXk6rzh314V_xHw_4TcV67K_w-u5FyncCBLHiOp4sOSHf8dWl23oANggJ48KFenjmwkBdrCL7sddGgTGk66jbEPopza81DXxcGmwvmDkHtnDYN1dRByX_e9kPvHEX_Rxs686fi3OJ6a3F5ncVzPoJ0H7HtCn4EheArJRO5afC86tzAH4EZGq9ArCHgK-dqstL7Qf6Ljly_foO57iJ4wBtBx3OlANrFKP-OxCuiIJmGkvNw636ExpwKe4ugVTD0MLXk6koeTS340khRoso1sLg1hTJ5AN7yG72awtes6tGrBRILrIxf04ntPCm3UdXYqbdm6YkscuOu1IR-gwxO0aJUhRqV005AnGxnYP1uaZB6LIgttggOyWBluhRNwB0SPHJ9TrNGOSyqaV2mr9FGrxNnCoGMLH7fNfyu0hxQLBqTD5NBG_yBAqDFkN_42t-fDWbTMZKZmVrZ2ySi29pcUIrv5QMZM2-eVs1zRweD8D06LEbsUAe0JlBvy4SfK_SW6JzvROjivwlRSnkA5Ctz0GTPHpL90GCN5ZIXQEAzt6eL8mWsutBlsk6xCbqnMXkUfZHrmngPpOCXJu1Y0Jhh6qnWjiVO_7fBUEXcngqWBPBzJZ_dzzbtG4CTfnra_e3iCwVlFnsvvCVo8EnQ6BFIQXEcQarLoteNojIe3rsdzESMMGVpF77JKtiEMujI_8ZrbzmdA48nKFQg7MGgPCQ8X0v6ZKOSa95iViC1XooXffvvXZ9Bdbyhvl5ec1xacDQaovBsCg3xrUcMwFK4nuwhRTT71EuuVkPtQS8kLDqvrcR27lrPR6ypFbQ_ZtFjvRh-4Vbl8WjfA0ySO0p7qCCHVLeAr9OiyAj253hBgnPSYk-UW1zFSnjuqFFltxs9aE4bTuKNV7EPOKcAj2TQOKQ6egMv40EZepe2fSftccymOzHLB8tKezbLDypxGRaeyyDwqOgZAfo5bvEcfz7fPOoRXkKF4I-WF-hlcdJfijk2gQw6q62TQv7bCzxV9bgHdTJ3GdWHBVSH6VDOZotzDjp-zQm5GJtlSpPz7jFtIKW6WIw0VQet04IMv9aDtJOWbZoJ_jMIyrVF3lLnqDXIvZh12Qu5349w8ix6gIi7NChWoREzbt4dJUqbnPHLGUz8a4QMbn32lxfJoISuy1OjR8zKbNfmI2prTmdeWTD9Go-yqxdsx-_ZdL3J0roQhH5YOPDVYZ-ecrSwfXtEBHp1Wl0PwaJAYhdxwemyoY-E7beNsOYvp5xLHH2R4JOEATxA9W9q55rVtWJhzI72pLYxwSOjRcllCz284POTdLBffrVt8OMLdLNkjdyzDxNhBH9mf5uO6PcO-yCo3ZZjdfxyGRkyYaWIX0FOAXN80b5NjF1SMN3UWZUad8xRSjoeS5GjOEo8xVMcw2-aV2pbqrrzDK9qubu5uV9flciOv2u3mdoWNur7Da3UnScq7683tqpRyU96sSN7KK72VS1mulvKaf0tZbOrVcl2Wm025ulndlJW4XlKH2hTGHDu2wysdQqLtZrmU6yuDFZmQXxmltDRAvskdsn688lt-ZlGlQxDXS6NDDK9Roo4mv2vu4Ou5V9aP8CuGkQOyUE9vnCMLHf6g6WXldcblwXduWW2nKY9L-4PzstxfJW-27wZSHdtUFbXrhNwzuunPovfuheoo5D7nxBNqzvnfAQAA__9bPvbL">