when should BOOL and bool be used in c

项目里,有个之前兄弟留下的库。硬生生将BOOL定义为bool,极为不和谐。今天半夜忽然回想起bool 跨模块返回值会出问题,遂查了查资料。看到有位小兄弟在stackoverflow上的提问。

http://stackoverflow.com/questions/830067/when-should-bool-and-bool-be-used-in-c

底下就有老兄做了解答

Matthew Wilson discusses BOOLbool, and similar in section 13.4.2 of Imperfect C++. Mixing the two can be problematic, since they generally have different sizes (and so pointers and references aren't interchangeable), and since bool isn't guaranteed to have any particular size. Trying to use typedefs or conditional compilating to smooth over the differences between BOOL and bool or trying to allow for a single Boolean type to work in both C and C++ is even worse:

#if defined(__cplusplus) || \
    defined(bool) /* for C compilation with C99 bool (macro) */
 typedef bool   bool_t;
#else
 typedef BOOL   bool_t;
#endif /* __cplusplus */

This approach means that a function's return type can differ depending on which language calls it; Wilson explains that he's seen more than one bug in his own code and others' that results from this. He concludes:

The solution to this imperfection is, as it so often is, abstinence. I never use  bool for anything that can possibly be accessed across multiple link units—dynamic/static libraries, supplied object files—which basically means not in functions or classes that appear outside of header files. The practical answer, such as it is, is to use a pseudo-Boolean type, which is the size of  int.

In short, he would agree with your approach.


================================================================================


If you wish to use a function written in C++ (for example embedded in DLL library) in managed program (for example in C#), you have to use BOOL. If you return bool, the result will always be true - this is known bug for a long time and apparently not yet resolved (VS 2010, .NET Framework 4).

=======================================================================================

还挖出来两篇老文章

BOOL vs. VARIANT_BOOL vs. BOOLEAN vs. bool

Still more ways of saying the same thing. Why so many?

Because each was invented by different people at different times to solve different problems.

BOOL is the oldest one. Its definition is simply

typedef int BOOL;

The C programming language uses "int" as its boolean type, and Windows 1.0 was written back when C was the cool language for systems programming.

Next came BOOLEAN.

typedef BYTE  BOOLEAN;

This type was introduced by the OS/2 NT team when they decided to write a new operating system from scratch. It lingers in Win32 in the places where the original NT design peeks through, like the security subsystem and interacting with drivers.

Off to the side came VARIANT_BOOL.

typedef short VARIANT_BOOL;
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#define VARIANT_FALSE ((VARIANT_BOOL)0)

This was developed by the Visual Basic folks. Basic uses -1 to represent "true" and 0 to represent "false", and VARIANT_BOOL was designed to preserve this behavior.

Common bug: When manipulating VARIANTs of type VT_BOOL, and you want to set a boolean value to "true", you must use VARIANT_TRUE. Many people mistakenly use TRUE or true, which are not the same thing as VARIANT_TRUE. You can cause problem with scripting languages if you get them confused. (For symmetry, you should also use VARIANT_FALSE instead of FALSE or false. All three have the same numerical value, however. Consequently, a mistake when manipulating "false" values is not fatal.)

Newest on the scene is bool, which is a C++ data type that has the value trueor false. You won't see this used much (if at all) in Win32 because Win32 tries to remain C-compatible.

(Note that C-compatible isn't the same as C-friendly. Although you can do COM from C, it isn't fun.)

===============================================================================


What's the difference between int and INT, long and LONG, etc?

When you go through Windows header files, you'll see types with names INT,LONGCHAR, and so on. What's the difference between these types and the uncapitalized ones?

Well, there isn't one any more.

What follows is an educated guess as to the story behind these types.

The application binary interface for an operating system needs to be unambiguous. Everybody has to agree on how parameters are passed, which registers are preserved, that sort of thing. A compiler need only enforce the calling convention rules at the boundary between the application and the operating system. When a program calls another function provided by that same program, it can use whatever calling convention it likes. (Not a true statement but the details aren't important here.) Therefore, a calling convention attribute on the declarations of each operating system function is sufficient to get everybody to agree on the interface.

However, another thing that everybody needs to agree on is the sizes of the types being passed to those functions or used in structures that cross the application/operating system boundary. The C language makes only very loose guarantees as to the sizes of each of the types, so language types like int andlong would be ambiguous. One compiler might decide that a long is a 32-bit integer, and another might decide that it's a 64-bit integer. To make sure that everybody was on the same page, the Windows header files defined "platform types" like INT and LONG with prescribed semantics that everybody could agree on. Each compiler vendor could tweak the Windows header file to ensure that the type definition for these platform types resulted in the value that Windows expected. One compiler might use typedef long LONG another might usetypedef __int32 LONG.

Okay, but this doesn't explain VOID. Maybe VOID was added for the benefit of compilers which didn't yet support the then-new ANSI C standard type void? Those older compilers could typedef int VOID; and functions that were declared as "returning VOID" would be treated as if they returned an integer that was always ignored. Or maybe it was just added to complete the set, who knows.

In the intervening years, most if not all compilers which target Windows have aligned their native types with Windows' platform types. An int is always a 32-bit signed integer, as is a long. As a result, the distinction between language types and platform types is now pretty much academic, and the two can be used interchangeably. New Windows functions tend to be introduced with language types, leaving platform types behind only for compatibility.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值