在宏条件中获取类型的大小

时间:2021-01-31 17:03:45

Is there some way to do something like this in c++, it seems sizeof cant be used there for some reason?

在c++中有什么方法可以这样做吗,看起来sizeof不能用于某些原因?

#if sizeof(wchar_t) != 2
#error "wchar_t is expected to be a 16 bit type."
#endif

7 个解决方案

#1


4  

I think things like BOOST_STATIC_ASSERT could help.

我认为BOOST_STATIC_ASSERT之类的东西可能会有帮助。

#2


14  

No, this can't be done because all macro expansion (#... things) is done in the pre-processor step which does not know anything about the types of the C++ code and even does not need to know anything about the language! It just expands/checks the #... things and nothing else!

不,这是不可能的,因为所有的宏扩展(#…事情)是在预处理步骤中完成的,它不知道c++代码的类型,甚至不需要知道任何关于语言的信息!它只是展开/检查#…东西,没有别的!

There are some other common errors, for example:

还有一些其他常见的错误,例如:

enum XY
{
  MY_CONST = 7,
};

#if MY_CONST == 7
  // This code will NEVER be compiled because the pre-processor does not know anything about your enum!
#endif //

You can only access and use things in #if that are defined via command line options to the compiler or via #define.

只有通过编译器的命令行选项或通过#define来定义,才能访问和使用#中的内容。

#3


7  

The preprocessor works without knowing anything about the types, even the builtin one.

预处理器在不知道类型的情况下工作,甚至不知道内置类型。

BTW, you can still do the check using a static_assert like feature (boost has one for instance, C++0X will have one).

顺便说一句,您仍然可以使用static_assert之类的特性进行检查(boost有一个特性,例如,c++ 0X将有一个)。

Edit: C99 and C++0X have also WCHAR_MIN and WCHAR_MAX macros in <stdint.h>

编辑:C99和c++ 0X在 中也有WCHAR_MIN和WCHAR_MAX宏

#4


3  

Wouldn't you get basically what you want (compile error w/o the fancy message) by using a C_ASSERT?

使用C_ASSERT难道您不会得到您想要的(编译错误w/o花哨的消息)吗?

#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]

#5


3  

sizeof() is a runtime compile-time function. You cannot call that in a preprocessor directive. I don't think you can check the size of wchar_t during preprocessing. (see Edit 2)

sizeof()是一个运行时编译时函数。不能在预处理器指令中调用它。我认为在预处理过程中不能检查wchar_t的大小。(参见编辑2)

Edit: As pointed out in comments, sizeof() is mostly calculated at compile time. In C99, it can be used at runtime for arrays.

编辑:正如注释中指出的,sizeof()大部分是在编译时计算的。在C99中,它可以在运行时用于数组。

Edit 2: You can do asserts at build time using the techniques described in this thread.

编辑2:您可以在构建时使用这个线程中描述的技术进行断言。

#6


1  

char _assert_wchar_t_is_16bit[ sizeof(wchar_t) == 2 ? 1 : -1];

#7


0  

I've developed some macros that will effectively allow you to use sizeof within a macro condition. They're in a header file that I've uploaded here (MIT license).

我已经开发了一些宏,可以有效地在宏条件下使用sizeof。它们在我上传的头文件中(MIT许可证)。

It will permit for code like this:

它将允许这样的代码:

#include <iostream>
#include "SIZEOF_definitions.h"

//You can also use SIZEOF_UINT in place of SIZEOF(unsigned, int)
// and UINT_BIT in place of SIZEOF_BIT(unsigned, int)
#if SIZEOF(unsigned, int) == 4
int func() { return SIZEOF_BIT(unsigned, int); }
#elif SIZEOF(unsigned, int) == 8
int func() { return 2 * SIZEOF_BIT(unsigned, int); }
#endif

int main(int argc, char** argv) {
  std::cout SIZEOF(unsigned, long, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, long, int) << '\n'
         << SIZEOF(unsigned, int)       << " chars, #bits = " << SIZEOF_BIT(unsigned, int)       << '\n'
         << SIZEOF(int)                 << " chars, #bits = " << SIZEOF_BIT(int)                 << '\n';
  std::cout << func() << std::endl;
  return 0;
}

Note the commas within SIZEOF(unsigned, long, int).

注意SIZEOF(unsigned, long, int)中的逗号。

#1


4  

I think things like BOOST_STATIC_ASSERT could help.

我认为BOOST_STATIC_ASSERT之类的东西可能会有帮助。

#2


14  

No, this can't be done because all macro expansion (#... things) is done in the pre-processor step which does not know anything about the types of the C++ code and even does not need to know anything about the language! It just expands/checks the #... things and nothing else!

不,这是不可能的,因为所有的宏扩展(#…事情)是在预处理步骤中完成的,它不知道c++代码的类型,甚至不需要知道任何关于语言的信息!它只是展开/检查#…东西,没有别的!

There are some other common errors, for example:

还有一些其他常见的错误,例如:

enum XY
{
  MY_CONST = 7,
};

#if MY_CONST == 7
  // This code will NEVER be compiled because the pre-processor does not know anything about your enum!
#endif //

You can only access and use things in #if that are defined via command line options to the compiler or via #define.

只有通过编译器的命令行选项或通过#define来定义,才能访问和使用#中的内容。

#3


7  

The preprocessor works without knowing anything about the types, even the builtin one.

预处理器在不知道类型的情况下工作,甚至不知道内置类型。

BTW, you can still do the check using a static_assert like feature (boost has one for instance, C++0X will have one).

顺便说一句,您仍然可以使用static_assert之类的特性进行检查(boost有一个特性,例如,c++ 0X将有一个)。

Edit: C99 and C++0X have also WCHAR_MIN and WCHAR_MAX macros in <stdint.h>

编辑:C99和c++ 0X在 中也有WCHAR_MIN和WCHAR_MAX宏

#4


3  

Wouldn't you get basically what you want (compile error w/o the fancy message) by using a C_ASSERT?

使用C_ASSERT难道您不会得到您想要的(编译错误w/o花哨的消息)吗?

#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]

#5


3  

sizeof() is a runtime compile-time function. You cannot call that in a preprocessor directive. I don't think you can check the size of wchar_t during preprocessing. (see Edit 2)

sizeof()是一个运行时编译时函数。不能在预处理器指令中调用它。我认为在预处理过程中不能检查wchar_t的大小。(参见编辑2)

Edit: As pointed out in comments, sizeof() is mostly calculated at compile time. In C99, it can be used at runtime for arrays.

编辑:正如注释中指出的,sizeof()大部分是在编译时计算的。在C99中,它可以在运行时用于数组。

Edit 2: You can do asserts at build time using the techniques described in this thread.

编辑2:您可以在构建时使用这个线程中描述的技术进行断言。

#6


1  

char _assert_wchar_t_is_16bit[ sizeof(wchar_t) == 2 ? 1 : -1];

#7


0  

I've developed some macros that will effectively allow you to use sizeof within a macro condition. They're in a header file that I've uploaded here (MIT license).

我已经开发了一些宏,可以有效地在宏条件下使用sizeof。它们在我上传的头文件中(MIT许可证)。

It will permit for code like this:

它将允许这样的代码:

#include <iostream>
#include "SIZEOF_definitions.h"

//You can also use SIZEOF_UINT in place of SIZEOF(unsigned, int)
// and UINT_BIT in place of SIZEOF_BIT(unsigned, int)
#if SIZEOF(unsigned, int) == 4
int func() { return SIZEOF_BIT(unsigned, int); }
#elif SIZEOF(unsigned, int) == 8
int func() { return 2 * SIZEOF_BIT(unsigned, int); }
#endif

int main(int argc, char** argv) {
  std::cout SIZEOF(unsigned, long, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, long, int) << '\n'
         << SIZEOF(unsigned, int)       << " chars, #bits = " << SIZEOF_BIT(unsigned, int)       << '\n'
         << SIZEOF(int)                 << " chars, #bits = " << SIZEOF_BIT(int)                 << '\n';
  std::cout << func() << std::endl;
  return 0;
}

Note the commas within SIZEOF(unsigned, long, int).

注意SIZEOF(unsigned, long, int)中的逗号。