Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why in g++ std::intmax_t is not a __int128_t?

My question is pretty simple: as std::intmax_t is defined as the maximum width integer type according to cppreference, why it does not correspond to __int128_t in GCC?

like image 738
Vincent Avatar asked Jan 21 '14 17:01

Vincent


People also ask

What is __ int128_t?

As an extension the integer scalar type __int128 is supported for targets which have an integer mode wide enough to hold 128 bits. Simply write __int128 for a signed 128-bit integer, or unsigned __int128 for an unsigned 128-bit integer.

What is Intmax_t?

Maximum Integer Types The concept behind intmax_t is simple enough: it is the largest integer type that your implementation and its standard library support in conjunction.


2 Answers

I believe this is a violation of the C and C++ standards -- either that, or gcc doesn't consider __int128_t to be an integer type.

The C standard (both the 1999 and 2011 editions) doesn't require intmax_t to be one of the standard types; it's required to be "a signed integer type capable of representing any value of any signed integer type". In particular, it can be an extended integer type -- and if there is a 128-bit extended integer type, then intmax_t must be at least 128 bits wide.

The C standard even suggests using implementation-defined keywords that "have the form of an identifier reserved for any use" as the names of extended integer types -- such as __int128_t.

The 2011 C++ standard adopts C99's extended integer types feature, and defers to the 1999 C standard for the definition of intmax_t and <stdint.h>.

So if __int128_t is an integer type within the meaning defined by the standard (which it certainly can be), and is, as the name implies, 128 bits wide, then intmax_t must be at least 128 bits wide.

As Stephen Canon's answer, changing intmax_t does require some work. The C and C++ standards do not recognize that as a justification for defining intmax_t incorrectly.

Of course all of this applies equally to uintmax_t.

#include <stdio.h>
#include <stdint.h>

int main(void) {
    __uint128_t huge = UINTMAX_MAX;
    huge ++;
    if (huge > UINTMAX_MAX) {
        puts("This should not happen");
    }
}

On my system (Linux x86_64, gcc 4.7.2), the above program prints:

This should not happen

If gcc conforms to the standard, then that should be possible only if __int128_t is not an integer type -- but quoting the gcc 4.8.2 manual (emphasis added):

As an extension the integer scalar type __int128 is supported for targets which have an integer mode wide enough to hold 128 bits. Simply write __int128 for a signed 128-bit integer, or unsigned __int128 for an unsigned 128-bit integer. There is no support in GCC for expressing an integer constant of type __int128 for targets with long long integer less than 128 bits wide.

I suppose one could argue that the "as an extension" phrase lets gcc off the hook here, justifying the existence of __int128_t under section 4 paragraph 6 of the standard:

A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.

rather than under section 6.2.6 paragraph 4:

There may also be implementation-defined extended signed integer types.

(I personally think that making intmax_t at least as wide as __int128_t, if it exists, would be more in keeping with the intent of the standard, even if it's (barely) possible to argue that it doesn't violate the letter of the standard.)

like image 85
Keith Thompson Avatar answered Oct 05 '22 23:10

Keith Thompson


Changing intmax_t requires not only changes to a compiler but also to numerous standard library functions that need to accept intmax_t arguments (and platform ABIs may define intmax_t as well). A compiler can unilaterally provide __int128_t as an extension, but it cannot unilaterally change the type intmax_t. That requires support from all of the standard library implementations that the compiler targets.

like image 23
Stephen Canon Avatar answered Oct 06 '22 00:10

Stephen Canon