我有这个编译时出现的错误“致命错误 C1017:无效的整数常量表达式”来自 Visual Studio。我该怎么做?
template <class B>
A *Create()
{
#if sizeof(B) > sizeof(A)
#error sizeof(B) > sizeof(A)!
#endif
...
}
我有这个编译时出现的错误“致命错误 C1017:无效的整数常量表达式”来自 Visual Studio。我该怎么做?
template <class B>
A *Create()
{
#if sizeof(B) > sizeof(A)
#error sizeof(B) > sizeof(A)!
#endif
...
}
预处理器不理解 sizeof()(或数据类型、标识符、模板或类定义,它需要理解所有这些东西才能实现 sizeof)。
您正在寻找的是一个静态断言(由编译器强制执行,它确实理解所有这些事情)。我为此使用Boost.StaticAssert :
template <class B>
A *Create()
{
BOOST_STATIC_ASSERT(sizeof(B) <= sizeof(A));
...
}
在编译器开始编译之前评估预处理器表达式。sizeof() 仅由编译器评估。
你不能用预处理器做到这一点。预处理器指令不能与诸如sizeof
. 此外,即使它们可以,它仍然不起作用,因为很早就从代码中消除了预处理器指令,所以不能期望它们作为稍后实例化的模板代码的一部分工作(这似乎是你想要的达到)。
正确的方法是使用某种形式的静态断言
template <class B>
A *Create()
{
STATIC_ASSERT(sizeof(B) <= sizeof(A));
...
}
那里有很多静态断言的实现。进行搜索并选择最适合您的。
sizeof() 不能在预处理器指令中使用。
预处理器在编译器之前运行(至少在逻辑上是这样)并且不了解用户定义的类型(并且不一定对内在类型有太多了解 - 预处理器的 int 大小可能与编译器目标不同。
无论如何,要做你想做的事,你应该使用STATIC_ASSERT()
. 请参阅以下答案:
有了 aSTATIC_ASSERT()
你就可以做到这一点:
template <class B>
A *Create()
{
STATIC_ASSERT( sizeof(A) >= sizeof( B));
return 0;
}
这不能用预处理器来完成。预处理器在编译器之前执行 - 因此在评估时尚未计算 NodeB 和 Node 的大小#if
。
您可以使用模板编程技术完成类似的事情。Andrei Alexandrescu 的《Modern C++ Design: Generic Programming and Design Patterns Applied》是一本关于该主题的优秀书籍。
这是一个来自网页的示例,它创建了一个模板 IF 语句。
从该示例中,您可以使用:
IF< sizeof(NodeB)<sizeof(Node), non_existing_type, int>::RET i;
它要么声明一个类型的变量,要么声明一个类型的int
变量non_existing_type
。假设如果模板 IF 条件评估为真,则不存在的类型符合其名称,将导致编译器错误。您可以重命名i
描述性内容。
使用这将是“滚动你自己的”静态断言,其中许多已经可用。我建议您在自己构建一个之后使用其中一个。
如果您对适用于 C 和 C++ 的编译时断言感兴趣,这是我开发的一个:
#define CONCAT2(x, y) x ## y
#define CONCAT(x, y) CONCAT2(x, y)
#define COMPILE_ASSERT(expr, name) \
struct CONCAT(name, __LINE__) { char CONCAT(name, __LINE__) [ (expr) ? 1 : -1 ]; }
#define CT_ASSERT(expr) COMPILE_ASSERT(expr, ct_assert_)
它的工作原理是当表达式为假时数组的大小为负(这是非法的)。通过进一步将其包装在结构定义中,这不会在运行时创建任何内容。
这已经解释过了,但请允许我详细说明为什么预处理器不能计算结构的大小。除了对简单的预处理器要求太多之外,还有一些编译器标志会影响结构的布局方式。
struct X {
short a;
long b;
};
这个结构可能是 6 字节或 8 字节长,这取决于编译器是否被告知出于性能原因对“b”字段进行 32 位对齐。预处理器不可能有这些信息。
我看到很多人说 sizeof 不能在预处理器指令中使用,但这不是全部,因为我经常使用以下宏:
#define STATICARRAYSIZE(a) (sizeof(a)/sizeof(*a))
例如:
#include <stdio.h>
#define STATICARRAYSIZE(a) (sizeof(a)/sizeof(*a))
int main(int argc, char*argv[])
{
unsigned char chars[] = "hello world!";
double dubls[] = {1, 2, 3, 4, 5};
printf("chars num bytes: %ld, num elements: %ld.\n" , sizeof(chars), STATICARRAYSIZE(chars));
printf("dubls num bytes: %ld, num elements: %ld.\n" , sizeof(dubls), STATICARRAYSIZE(dubls));
}
产量:
orion$ ./a.out
chars num bytes: 13, num elements: 13.
dubls num bytes: 40, num elements: 5.
然而
我也无法在 gcc 4.2.1 下的 #if 语句中编译 sizeof()。例如,这不会编译:
#if (sizeof(int) == 2)
#error uh oh
#endif
任何见解将不胜感激。
使用 MSVC,此代码为我编译:
const int cPointerSize = sizeof(void*);
const int cFourBytes = 4;`
#if (cPointerSize == cFourBytes)
...
然而这(应该同样工作)不:
#if ( sizeof(void*) == 4 )
...