Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3340824
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T00:39:08+00:00 2026-05-18T00:39:08+00:00

I experienced some odd behavior while using C++ type traits and have narrowed my

  • 0

I experienced some odd behavior while using C++ type traits and have narrowed my problem down to this quirky little problem for which I will give a ton of explanation since I do not want to leave anything open for misinterpretation.

Say you have a program like so:

#include <iostream>
#include <cstdint>

template <typename T>
bool is_int64() { return false; }

template <>
bool is_int64<int64_t>() { return true; }

int main()
{
 std::cout << "int:\t" << is_int64<int>() << std::endl;
 std::cout << "int64_t:\t" << is_int64<int64_t>() << std::endl;
 std::cout << "long int:\t" << is_int64<long int>() << std::endl;
 std::cout << "long long int:\t" << is_int64<long long int>() << std::endl;

 return 0;
}

In both 32-bit compile with GCC (and with 32- and 64-bit MSVC), the output of the program will be:

int:           0
int64_t:       1
long int:      0
long long int: 1

However, the program resulting from a 64-bit GCC compile will output:

int:           0
int64_t:       1
long int:      1
long long int: 0

This is curious, since long long int is a signed 64-bit integer and is, for all intents and purposes, identical to the long int and int64_t types, so logically, int64_t, long int and long long int would be equivalent types – the assembly generated when using these types is identical. One look at stdint.h tells me why:

# if __WORDSIZE == 64
typedef long int  int64_t;
# else
__extension__
typedef long long int  int64_t;
# endif

In a 64-bit compile, int64_t is long int, not a long long int (obviously).

The fix for this situation is pretty easy:

#if defined(__GNUC__) && (__WORDSIZE == 64)
template <>
bool is_int64<long long int>() { return true; }
#endif

But this is horribly hackish and does not scale well (actual functions of substance, uint64_t, etc). So my question is: Is there a way to tell the compiler that a long long int is the also a int64_t, just like long int is?


My initial thoughts are that this is not possible, due to the way C/C++ type definitions work. There is not a way to specify type equivalence of the basic data types to the compiler, since that is the compiler’s job (and allowing that could break a lot of things) and typedef only goes one way.

I’m also not too concerned with getting an answer here, since this is a super-duper edge case that I do not suspect anyone will ever care about when the examples are not horribly contrived (does that mean this should be community wiki?).


Append: The reason why I’m using partial template specialization instead of an easier example like:

void go(int64_t) { }

int main()
{
    long long int x = 2;
    go(x);
    return 0;
}

is that said example will still compile, since long long int is implicitly convertible to an int64_t.


Append: The only answer so far assumes that I want to know if a type is 64-bits. I did not want to mislead people into thinking that I care about that and probably should have provided more examples of where this problem manifests itself.

template <typename T>
struct some_type_trait : boost::false_type { };

template <>
struct some_type_trait<int64_t> : boost::true_type { };

In this example, some_type_trait<long int> will be a boost::true_type, but some_type_trait<long long int> will not be. While this makes sense in C++’s idea of types, it is not desirable.

Another example is using a qualifier like same_type (which is pretty common to use in C++0x Concepts):

template <typename T>
void same_type(T, T) { }

void foo()
{
    long int x;
    long long int y;
    same_type(x, y);
}

That example fails to compile, since C++ (correctly) sees that the types are different. g++ will fail to compile with an error like: no matching function call same_type(long int&, long long int&).

I would like to stress that I understand why this is happening, but I am looking for a workaround that does not force me to repeat code all over the place.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T00:39:08+00:00Added an answer on May 18, 2026 at 12:39 am

    You don’t need to go to 64-bit to see something like this. Consider int32_t on common 32-bit platforms. It might be typedef‘ed as int or as a long, but obviously only one of the two at a time. int and long are of course distinct types.

    It’s not hard to see that there is no workaround which makes int == int32_t == long on 32-bit systems. For the same reason, there’s no way to make long == int64_t == long long on 64-bit systems.

    If you could, the possible consequences would be rather painful for code that overloaded foo(int), foo(long) and foo(long long) – suddenly they’d have two definitions for the same overload?!

    The correct solution is that your template code usually should not be relying on a precise type, but on the properties of that type. The whole same_type logic could still be OK for specific cases:

    long foo(long x);
    std::tr1::disable_if(same_type(int64_t, long), int64_t)::type foo(int64_t);
    

    I.e., the overload foo(int64_t) is not defined when it’s exactly the same as foo(long).

    [edit]
    With C++11, we now have a standard way to write this:

    long foo(long x);
    std::enable_if<!std::is_same<int64_t, long>::value, int64_t>::type foo(int64_t);
    

    [edit]
    Or C++20

    long foo(long x);
    int64_t foo(int64_t) requires (!std::is_same_v<int64_t, long>);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've experienced rather strange behavior of JSTL forEach tag. I have some bean called
I have some experience making multiplayer turn-based games using sockets, but I've never attempted
I was wondering if anyone here had some experience writing this type of script
I am a web-developer working in PHP. I have some limited experience with using
I'm new to NAnt but have some experience with Ant and CruiseControl. What I
I am working on a rails application (I have some experience with rails). But,
I've got some experience with Bash , which I don't mind, but now that
I've had some experience with Pygame, but there seems to be a lot of
I was thinking that i wanted to gain some experience in the new asp.net
I'm interested in implementing a Forth system, just so I can get some experience

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.