Reputation: 133014
I was just taking a C++ test and I got the following question wrong:
Q: What is the output of the following program?
#include <iostream>
#include <stdint.h>
using namespace std;
int main() {
int a = 0;
for (int8_t i = 1; i > 0; i <<= 1)
a++;
cout << a;
return 0;
}
There were the following answers to choose from
The "correct" answer was 7. If there was "Implementation-Defined Behavior" in the answers, I would choose that, so I chose Undefined Behavior which was sort of the closest. I understand that in sign-and-magnitute, 1's complement, and 2's complement the answer will be 7. But doesn't the C++ standard theoretically allow any other number representations? For example, sign and magnitude, but 0 means negative?
Am I correct in that the real correct answer to this question should be Implementation-Defined Behavior, and if not, could you please explain why the answer is 7 regardless of the implementation?
I read the comments to the question and it appears that initially the type of a
was char, which apparently had raised a lot of complaints about whether char
is signed or not, so the testsetter changed it to int8_t. As a bonus question, is <stdint.h>
part of C++? O_O
Upvotes: 12
Views: 764
Reputation: 247999
I would say it is undefined (and not implementation-defined) for a different reason.
From 5.8:3
The value of
E1 << E2
is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
Upvotes: 18
Reputation: 96810
Since the immediate question was answered, I'll answer the bonus question: <stdint.h>
is a C header which is available in C++. However, use the modern C++ header <cstdint>
instead.
Upvotes: 3
Reputation: 180917
If the implementation provides the optional int8_t
, the answer should be correct, from the C99 draft which C++11 references regarding stdint;
7.18.1.1 Exact-width integer types
The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, int8_t denotes a signed integer type with a width of exactly 8 bits.
Upvotes: 7