首页 > 解决方案 > 宏中的 Sizeof(SIMD 向量)问题

问题描述

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

#include <stdio.h>

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

int main(){
    printf("%zu %zu\n", 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 %zu\n", A, B); // print out 4 0
}

有什么问题?

标签: cc-preprocessorsimd

解决方案


请记住,宏不是变量:它们只是替换的标记。所以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/16is22/4is 0

出于这个原因,您应该始终将扩展为表达式的宏括起来:

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

推荐阅读