Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
371 views
in Technique[技术] by (71.8m points)

c++ - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...