Блог пользователя I_love_tigersugar

Автор I_love_tigersugar, история, 8 лет назад, По-английски

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?

  • Проголосовать: нравится
  • +24
  • Проголосовать: не нравится

»
8 лет назад, # |
  Проголосовать: нравится +19 Проголосовать: не нравится

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 лет назад, # ^ |
      Проголосовать: нравится -8 Проголосовать: не нравится

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

    • »
      »
      »
      8 лет назад, # ^ |
      Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

      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 лет назад, # ^ |
      Проголосовать: нравится +63 Проголосовать: не нравится

    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';