英文:
How can I use the "builtin" function __builtin_ctzll in a VS C++ Project?
问题
我已经了解到了__builtin_ctzll
用于快速计算64位整数的末尾零位数,通过这篇帖子Intrinsic to count trailing zero bits in 64-bit integers?。
我是一个C++初学者,不知道如何包含这个函数。
我尝试使用#include
,但那没有任何意义。我发现这个"builtin"来自GNU,但我不知道如何处理这些信息。我应该如何为我的项目准备正确的库/扩展?
英文:
I have found out about __builtin_ctzll
to count trailing zeros of a 64bit int really fast through the post Intrinsic to count trailing zero bits in 64-bit integers?.
I'm a beginner to C++ and don't know how to include this function.
I tried to use #include
, but that didn't make any sense. I found out that this "builtin" comes from GNU, but I didn't know what to do with that information. How can I prepare the right library/extension for my project?
答案1
得分: 9
对于无符号类型,您可以使用标准/可移植的C++20函数std::countr_zero
。
它将返回与GCC的__builtin_ctzll
相同的结果,但请注意:
如果在使用__builtin_ctzll
时值为0
,结果是未定义的,而std::countr_zero(0ull)
将返回整数中的位数。
在VS2022中,您将在菜单项目\属性\配置属性\常规
的C++语言标准
中找到语言设置。默认设置为C++14
。将其更改为C++20
(或Preview
,如果您想尝试一些C++23功能)。
英文:
For unsigned
types, you can use the standard/portable C++20 function std::countr_zero
.
It'll return the same thing as GCC's __builtin_ctzll
, but note:
If the value is 0
when using __builtin_ctzll
, the result is undefined, while std::countr_zero(0ull)
will return the number of bits in the integer.
In VS2022, you'll find the language setting in the menu Project\Properties\Configuration Properties\General
C++ Language Standard
. It's set to C++14
by default. Change that to C++20
(or Preview
if you'd like to try out some C++23 features too).
答案2
得分: 2
如果您正在使用MSVC,可以使用其_BitScanReverse64内置函数(或者它喜欢称之为“编译器内置函数”),以复制GCC的__builtin_ctzll
的行为。此函数提供第一个非零位位置的索引,这等同于尾随零的数量。
因此,
int pos = __builtin_ctzll(x);
可以替换为
unsigned long pos;
unsigned char is_nonzero = _BitScanReverse64(&pos, x);
这个内置函数也可以说比__builtin_ctzll
更好,因为它强制检查参数是否为零。GCC的__builtin_ctzll
将包含对该情况进行检查的负担交给用户,并将零参数的行为留给未定义。
请注意,与之类似命名的__lzcnt
系列内置函数在MSVC中计算_前导_零(类似于GCC的clz
系列),而不是尾随零。出于某种原因,MSVC没有提供类似命名的__tzcnt
系列内置函数。
英文:
If you're using MSVC, you can use its _BitScanReverse64 builtin (or "compiler intrinsic" as it likes to call them) to replicate the behavior of GCC's __builtin_ctzll
. This function provides the index of the first non-zero bit position, which is equivalent to the number of trailing zeros.
So,
int pos = __builtin_ctzll(x);
can be replaced by
unsigned long pos;
unsigned char is_nonzero = _BitScanReverse64(&pos, x);
This intrinsic is also arguably nicer than __builtin_ctzll
since it forces a check for whether the argument is zero. GCC's __builtin_ctzll
puts the burden to include a check for that case on the user, and leaves behavior for a zero argument undefined.
<sup>Note that the similarly named __lzcnt
family of intrinsics in MSVC counts leading zeros (like GCC's clz
family), not trailing zeros. For whatever reason, MSVC doesn't provide a like-named family of __tzcnt
intrinsics.</sup>
答案3
得分: 1
正如其名,"builtin" 函数实际上是直接内建于提供它们的编译器中的。它们只是编译器为之提供特殊行为的特殊标识符。您无需加载任何额外的库或包含任何头文件即可使用它们。编译器会本地识别它们并提供它们特有的、特定于编译器的行为。
要使用特定的内建函数,唯一的方法是使用提供它的编译器。例如,函数 __builtin_ctzl
在 GCC 中作为内建函数提供。如果您使用 GCC 作为您的编译器,您将能够在不需要任何额外步骤的情况下使用它。如果您使用不同的编译器,您将需要考虑另一种解决方案,比如您的编译器提供的类似的内建函数或类似的库函数。
英文:
As the name suggests, "builtin" functions are literally built into the compiler that provides them. They're just special identifiers that the compiler provides special behavior for. You do need to load any additional libraries or include any header files to use them. The compiler will natively recognize them and provide their special, compiler-specific behavior.
The only way to use a particular builtin function is to use the compiler that provides it. For example, the function __builtin_ctzl
is provided as a builtin in GCC. If you use GCC as your compiler, you will be able to use it without any additional steps. If you use a different compiler, you'll need to look into a different solution, such as a similar builtin that your compiler provides or a similar library function.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论