Armen Tsirunyan
Armen Tsirunyan

Reputation: 133014

C++ Test - Does sign bit 1 always mean negative?

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

Answers (3)

Stack Overflow is garbage
Stack Overflow is garbage

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

David G
David G

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

Joachim Isaksson
Joachim Isaksson

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

Related Questions