|
2035 | 2035 | }; |
2036 | 2036 | \end{codeblock} |
2037 | 2037 | \end{example} |
2038 | | - |
2039 | | - |
2040 | | -\rSec1[ub.cpp]{\ref{cpp}: Preprocessing directives} |
2041 | | - |
2042 | | -\rSec2[ub.cpp.cond]{Conditional inclusion} |
2043 | | - |
2044 | | -\pnum |
2045 | | -\ubxref{cpp.cond.defined} \\ |
2046 | | -If the token defined is generated as a result of this replacement process or use of |
2047 | | -the defined unary operator does not match one of the two specified forms prior to macro replacement, the |
2048 | | -behavior is undefined. |
2049 | | - |
2050 | | -\pnum |
2051 | | -\begin{example} |
2052 | | -\begin{codeblock} |
2053 | | -#define A |
2054 | | -#define B defined(A) |
2055 | | -#if B // undefined behavior, \tcode{defined} is generated by macro replacement for controlling expression |
2056 | | -#endif |
2057 | | -\end{codeblock} |
2058 | | -\end{example} |
2059 | | - |
2060 | | - |
2061 | | -\rSec2[ub.cpp.include]{Source file inclusion} |
2062 | | - |
2063 | | -\pnum |
2064 | | -\ubxref{cpp.include.one.of.two.forms} \\ |
2065 | | -If the an include directive after replacement does not match one of the two forms |
2066 | | -outlined [cpp.indlude]\iref{cpp.include} then the behavior is undefined |
2067 | | - |
2068 | | -\pnum |
2069 | | -\begin{example} |
2070 | | -\begin{codeblock} |
2071 | | -#include " // undefined behavior, does not match one of the allowable forms |
2072 | | -\end{codeblock} |
2073 | | -\end{example} |
2074 | | - |
2075 | | - |
2076 | | -\rSec2[ub.cpp.replace]{Macro replacement} |
2077 | | - |
2078 | | -\pnum |
2079 | | -\ubxref{cpp.replace.macro.pptoken} \\ |
2080 | | -If there are sequences of preprocessing tokens within the list of arguments to a function-like macro |
2081 | | -that would otherwise act as preprocessing directives, the behavior is undefined. |
2082 | | - |
2083 | | -\pnum |
2084 | | -\begin{example} |
2085 | | -\begin{codeblock} |
2086 | | -#define M(d, n) d = n |
2087 | | - |
2088 | | -void f(int x) { |
2089 | | - M(x, |
2090 | | -#ifdef D // undefined behavior, preprocessing directive |
2091 | | - 16 |
2092 | | -#else // undefined behavior, preprocessing directive |
2093 | | - 32 |
2094 | | -#endif // undefined behavior, preprocessing directive |
2095 | | - ); |
2096 | | -} |
2097 | | - |
2098 | | -int main() { |
2099 | | - int x; |
2100 | | - f(x); |
2101 | | -} |
2102 | | -\end{codeblock} |
2103 | | -\end{example} |
2104 | | - |
2105 | | - |
2106 | | -\rSec2[ub.cpp.stringize]{The \# operator} |
2107 | | - |
2108 | | -\pnum |
2109 | | -\ubxref{cpp.stringize.invalid.char} \\ |
2110 | | -If an invalid character results from using the stringize operator the behavior is undefined. |
2111 | | - |
2112 | | -\pnum |
2113 | | -\begin{example} |
2114 | | -\begin{codeblock} |
2115 | | -#define s_lit(x) #x |
2116 | | -s_lit( \ ) // stringizes to "\tcode{\textbackslash}"", which is not a valid token |
2117 | | -\end{codeblock} |
2118 | | -\end{example} |
2119 | | - |
2120 | | - |
2121 | | -\rSec2[ub.cpp.concat]{The \#\# operator} |
2122 | | - |
2123 | | -\pnum |
2124 | | -\ubxref{cpp.concat.invalid.preprocessing.token} \\ |
2125 | | -If an invalid preprocessing token results from using the concat operator the behavior is undefined. |
2126 | | - |
2127 | | -\pnum |
2128 | | -\begin{example} |
2129 | | -\begin{codeblock} |
2130 | | -#define cat(x, y) x##y |
2131 | | - |
2132 | | -void f() { |
2133 | | - cat(/, /) // undefined behavior // is not a valid preprocessing token |
2134 | | -} |
2135 | | -\end{codeblock} |
2136 | | -\end{example} |
2137 | | - |
2138 | | - |
2139 | | -\rSec2[ub.cpp.line]{Line control} |
2140 | | - |
2141 | | -\pnum |
2142 | | -\ubxref{cpp.line.zero.or.overflow} \\ |
2143 | | -When using the \tcode{\#line} directive, if the digit sequence |
2144 | | -specifies zero or a number greater than 2147483647, the behavior is undefined. |
2145 | | - |
2146 | | -\pnum |
2147 | | -\begin{example} |
2148 | | -\begin{codeblock} |
2149 | | -#line 4294967295 // undefined behavior, number greater than 2147483647 |
2150 | | - |
2151 | | -int main() { return notdefined; } |
2152 | | -\end{codeblock} |
2153 | | -\end{example} |
2154 | | - |
2155 | | -\pnum |
2156 | | -\ubxref{cpp.line.pptoken.not.match} \\ |
2157 | | -When using the \grammarterm{pp-tokens} variant of the \tcode{\#line} directive, if the directive resulting after all replacements does not match |
2158 | | -one of the two previous forms, the behavior is undefined. |
2159 | | - |
2160 | | -\pnum |
2161 | | -\begin{example} |
2162 | | -\begin{codeblock} |
2163 | | -#define cat(a, b) a##b |
2164 | | -#line cat(10, e20) |
2165 | | -\end{codeblock} |
2166 | | -\end{example} |
2167 | | - |
2168 | | -\rSec2[ub.cpp.predefined]{Predefined macro names} |
2169 | | - |
2170 | | -\pnum |
2171 | | -\ubxref{cpp.predefined.define.undef} \\ |
2172 | | -If any of the pre-defined macro names in [cpp.predefined], or the identifier defined, is the subject of a \tcode{\#define} |
2173 | | -or a \tcode{\#undef} preprocessing directive, the behavior is undefined. |
2174 | | - |
2175 | | -\pnum |
2176 | | -\begin{example} |
2177 | | -\begin{codeblock} |
2178 | | -#define __cplusplus 300012L |
2179 | | -\end{codeblock} |
2180 | | -\end{example} |
0 commit comments