c语言 - 宏中的大小(SIMD 矢量)问题



我想定义几个宏来计算类型的大小。以下是正常运行的示例。

#include <stdio.h>
#define A sizeof(long long) / sizeof(int)
#define B 36 / A
int main(){
printf("%zu %zun", A, B); // print out: 2 1
}

虽然在使用 SIMD 向量时会变得很奇怪,例如(A 的定义)

#include <x86intrin.h>
#include <stdio.h>
#define A sizeof(__m128i) / sizeof(int)
#define B 36 / A
int main(){
printf("%zu %zun", A, B); // print out 4 0
}

问题出在哪里?

请记住,宏不是变量:它们只是替换的标记。 所以B扩展到

36 / sizeof(__m128i) / sizeof(int)

C 和 C++ 中的划分从左到右关联,因此这相当于

(36 / sizeof(__m128i)) / sizeof(int) 

如果sizeof(__m128i)为 16,sizeof(int)为 4,则此表达式为(36 / 16) / 4。 现在 C 和 C++ 中的整数除法,所以36/1622/40

因此,应始终将扩展到表达式的宏括起来:

#define A (sizeof(__m128i) / sizeof(int))
#define B (36 / A)

如果使用C++,更好的解决方案是根本不使用宏;C++中的常量功能非常齐全,并避免此问题。

constexpr std::size_t A = sizeof(__m128i) / sizeof(int);
constexpr std::size_t B = 36 / A;

#define A sizeof(__m128i) / sizeof(int)
#define B 36 / A

然后宏B将扩展为36 / sizeof(__m128i) / sizeof(int)评估为(36 / sizeof(__m128i)) / sizeof(int)

第一次除法的结果将为零,零除以任何值为零。这就是你得到的结果。

与使用宏时一样,解决方案几乎总是在宏定义中添加显式括号:

#define A (sizeof(__m128i) / sizeof(int))
#define B (36 / A)

相关内容

  • 没有找到相关文章

最新更新