Take this code:
int issuecode(int i)
{
return 2 * i;
}
int main(int argc, char **argv)
{
return issuecode(argc);
}
The way I understand it, if compiled as a C program, it will have undefined behaviour. I reason based on these standard quotes:
C99, 7.26 (or C11, 7.31)
The following names are grouped under individual headers for convenience. All external names described below are reserved no matter what headers are included by the program.
C99, 7.26.2 (or C11, 7.31.2)
Function names that begin with either
isorto, and a lowercase letter may be added to the declarations in the<ctype.h>header.
C99, 7.1.3 (or C11, 7.1.3)
Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.
[...]
- All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.
[...] If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
Based on the above, I believe the function name issuecode is actually reserved for use in <ctype.h>, and so the program technically has UB.
Question 0 (sanity check): Is my reading of the standard correct and the program's behaviour technically undefined?
Question 1: Will the program have UB if compiled as C++ code?
I believe the answer is "no," as from the following quotes, I'd say the "future library directions" of C are not part of the C++ standard library, but I am not really sure.
C++11, 21.7
Tables 74, 75, 76, 77, 78, and 79 describe headers
<cctype>,<cwctype>,<cstring>,<cwchar>,<cstdlib>(character conversions), and<cuchar>, respectively.The contents of these headers shall be the same as the Standard C Library headers
<ctype.h>,<wctype.h>,<string.h>,<wchar.h>, and<stdlib.h>and the C Unicode TR header , respectively, with the following modifications:
None of the "following modifications" mentions the additional reserved identifiers. Table 74 is a taxative list of function names like isdigit and isalnum.
C++11, C.2
1. This subclause summarizes the contents of the C++ standard library included from the Standard C library. It also summarizes the explicit changes in definitions, declarations, or behavior from the Standard C library noted in other subclauses (17.6.1.2, 18.2, 21.7).
7. The C++ standard library provides 209 standard functions from the C library, as shown in Table 153.
Again, table 153 is a taxative list.
Question 2: Assuming I am wrong on question 1 and the program actually does have UB in C++ as well, would the following change affect this?
namespace foo {
int issuecode(int i)
{
return 2 * i;
}
}
using namespace foo;
int main(int argc, char **argv)
{
return issuecode(argc);
}
Note: The standard quotes are taken from drafts N1256 (C99), N1570 (C11) and N3242 (C++11), which are the latest publically available drafts for the respective language versions.
std::namespace. (The best would be to test this on a DS9K, though.) - user529758ishas UB? If so, I've been writing UB all the time... - Andy Prowl