问题
While I was putting together a to-uppercase function in C++ I noticed that I did not receive the expected output in C.
C++ function
#include <iostream>
#include <cctype>
#include <cstdio>
void strupp(char* beg)
{
while (*beg++ = std::toupper(*beg));
}
int main(int charc, char* argv[])
{
char a[] = "foobar";
strupp(a);
printf("%s\n", a);
return 0;
}
Output as expected:
FOOBAR
C function
#include <ctype.h>
#include <stdio.h>
#include <string.h>
void strupp(char* beg)
{
while (*beg++ = toupper(*beg));
}
int main(int charc, char* argv[])
{
char a[] = "foobar";
strupp(a);
printf("%s\n", a);
return 0;
}
The output is the expected result with the first character missing
OOBAR
Does anyone know why the result gets truncated while compiling in C?
回答1:
The problem is that there is no sequence point in
while (*beg++ = toupper(*beg));
So we have undefined behavior. What the compiler is doing in this case is evaluating beg++
before toupper(*beg)
In C where in C++ it is doing it the other way.
回答2:
while (*beg++ = std::toupper(*beg));
leads to undefined behavior.
Whether *beg++
is sequenced before or after std::toupper(*beg)
is unspecified.
The simple fix is to use:
while (*beg = std::toupper(*beg))
++beg;
回答3:
The line
while (*beg++ = toupper(*beg));
contains a side effect on an entity that's being used twice. You can not know, whether or not beg++ is executed before or after the *beg (inside the toupper). You're just lucky that both implementations show both behaviors, as I'm pretty sure it's the same for C++. (However, there were some rule changes for c++11, which I'm not certain of - still, it's bad style.)
Just move the beg++ out of the condition:
while (*beg = toupper(*beg)) beg++;
回答4:
with respect to above answer, the 'f' is never passed inside function, you should try using this:
while ((*beg = (char) toupper(*beg))) beg++;
来源:https://stackoverflow.com/questions/33086007/c-string-to-uppercase-in-c-and-c