I_love_tigersugar's blog

By I_love_tigersugar, history, 8 years ago, In English

The easy problem in SRM 685 is the N-th time I failed because of using __builtin_popcount instead of __builtin_popcountll. As a result, a new line has been added to my template code:

#define __builtin_popcount __builtin_popcountll

Btw, does anyone have an idea why C++ doesn't merge the 2 above functions into one to avoid such silly mistakes?

  • Vote: I like it
  • +24
  • Vote: I do not like it

»
8 years ago, # |
  Vote: I like it +19 Vote: I do not like it

The reason that you have 2 different functions is that, __builtin_popcount and __builtin_popcountll are defined in C. In C, unlike C++, you don't have function overloading. For example, you can't do the following in C:

int f(int a) {
}
int f(char a) {
}

Thus, you have 2 different functions. The same happened with abs, llabs, fabs..

  • »
    »
    8 years ago, # ^ |
      Vote: I like it -8 Vote: I do not like it

    But abs(123.5) still returns 123.5 though. Using abs for long long also works as well.

    • »
      »
      »
      8 years ago, # ^ |
      Rev. 3   Vote: I like it 0 Vote: I do not like it

      Are you trying C++ or C? In C++ it works, as they redefined abs function (see reference). In C, the following code proves my point:

      int main() {
          long long a = abs(1000111000111000LL);
          printf("%lld\n", a);  // output 2095433624
          long long b = 1000111000111000LL;
          printf("%lld\n", b);  // output 1000111000111000
      }
      
      • »
        »
        »
        »
        8 years ago, # ^ |
        Rev. 2   Vote: I like it 0 Vote: I do not like it

        Ops, I thought you meant C++.

      • »
        »
        »
        »
        8 years ago, # ^ |
          Vote: I like it +24 Vote: I do not like it

        So what the problem to redefine __builtin_popcount in C++?

  • »
    »
    8 years ago, # ^ |
      Vote: I like it +63 Vote: I do not like it

    In C, unlike C++, you don't have function overloading

    in C11 you have a special feature called "generic selection" for such cases:

    #define POPCNT(a) _Generic((a), int: __builtin_popcount(a), \  
                                    long long: __builtin_popcountll(a))  
    
    // ...
    
    cout << POPCNT(55) << '\n';