简体   繁体   English

具有布尔返回值的功能,仅设置整个寄存器的1个字节

[英]Function with bool return value, only set 1 byte of the entire register

I have the following piece of code which is a part of api (cdecl). 我有以下一段代码是api(cdecl)的一部分。 In MSVC++ the sizeof bool is 1 byte, but since bool is implementation defined, some programs compiled by other compiler/the author incorrectly define function signature may treat bool as >1 byte and calling the check below may return true on their side of programs. 在MSVC ++中,bool的大小为1个字节,但是由于bool是由实现定义的,因此其他编译器/作者不正确定义函数签名的某些程序可能会将bool视为> 1字节,因此调用下面的检查可能会在程序一侧返回true。

virtual bool isValid()
{
    return false;
    // ^ code above in asm: xor al, al
}

To avoid this, I put an inline asm, xor eax, eax before the return - but I feel it a bit hacky and it of course will not work on x64 due to lack of inline assembler support. 为了避免这种情况,我在返回之前放置了一个内联asm, xor eax, eax但我觉得它有点hacky,并且由于缺乏内联汇编程序支持,因此它当然不能在x64上运行。

Using #define bool int will work but it is not I wanted, as I have structs that have bool datatype inside it and using this will causes corruption. 使用#define bool int可以工作,但不是我想要的,因为我的结构内部具有bool数据类型,使用它会导致损坏。

Is there anything like intrinsics that can zeroed the eax/rax register or anything that can solve this problem? 是否有诸如内在函数之类的东西可以将eax / rax寄存器清零,或者什么可以解决此问题?

There's nothing that will do what you're asking for. 没有什么可以满足您的要求。 Your problem needs a much different solution. 您的问题需要完全不同的解决方案。

First any code that "incorrectly define function signature" is broken an needs to fixed. 首先,任何“错误定义函数签名”的代码都需要修复。 It's never the solution to work around it in other code. 在其他代码中解决它从来都不是解决方案。

Next your problem is like more than just bool being implementation defined, the C++ standard makes a whole host of things are implementation defined. 接下来,您的问题不只是实现实现定义bool ,C ++标准还使很多事情都实现实现定义。 So much so that two different C++ compilers are rarely have a compatible ABIs. 如此之多,以至于两个不同的C ++编译器很少具有兼容的ABI。 If your code provides C++ interfaces for the use of code compiled by other people you'll probably need to produce separately compiled binaries, whether in the form of object files, static libraries, DLLs or executables, for each different compiler you want to support. 如果您的代码提供了C ++接口供其他人使用的编译代码使用,则可能需要为要支持的每个不同的编译器生成单独编译的二进制文件,无论是目标文件,静态库,DLL还是可执行文件的形式。 In fact you may need to provide separate binaries for each version of each compiler. 实际上,您可能需要为每个编译器的每个版本提供单独的二进制文件。

There are two C++ compilers the try to be compatible with the Microsoft C++ ABI. 有两种C ++编译器试图与Microsoft C ++ ABI兼容。 The first is Intel's C++ compiler and the second is the Windows port of clang . 第一个是Intel的C ++编译器 ,第二个是clang的Windows端口 The clang implementation is notably still a work in progress. clang的实现显然仍在进行中。 You may still need to create separate versions for each version of the Microsoft C/C++ runtime libraries your code is compiled with. 您可能仍需要为编译代码所使用的每个版本的Microsoft C / C ++运行时库创建单独的版本。

You can potentially reduce the number of different versions of binaries that you need to distribute by providing a pure C interface to your code. 通过为代码提供纯C接口,可以潜在地减少需要分发的不同版本的二进制文件的数量。 A pure C interface means using only C data types and only functions declared as extern "C" . 纯C接口意味着仅使用C数据类型和仅声明为extern "C"函数。 While things like classes, member functions, templates, RTTI and exceptions can be used in your implementation the can't be used as part of your public interface. 虽然类,成员函数,模板,RTTI和异常之类的东西可以在实现中使用,但不能用作公共接口的一部分。 An exception are COM-like interfaces, classes with nothing but public pure virtual functions. 类似于COM的接口是一个例外,类仅具有公共纯虚函数。 Since C compilers for Windows all use essentially the same C ABI and support COM interfaces, compatibility issues are less likely to be an issue. 由于Windows的C编译器基本上都使用相同的C ABI并支持COM接口,因此不太可能出现兼容性问题。 However the bool type (actually the _Bool type in C) is probably not safe to use, since it's a relatively recent addition to the C language. 但是, bool类型(实际上是C中的_Bool类型)可能不安全使用,因为它是C语言中相对较新的功能。 Use int in your C interfaces instead. 请在您的C接口中使用int

Note that because of C/C++ runtime differences even if you all you want to do distribute compiled binaries for use with Microsoft's Visual C++ compiler you may still need to distribute versions for each version of the compiler. 请注意,由于C / C ++运行时的差异,即使您要分发与Microsoft Visual C ++编译器一起使用的已编译二进制文件,您仍可能需要为每个版本的编译器都分发版本。 That's because each version comes with a different runtime implementation and which have data structures with incompatible internal layouts. 这是因为每个版本都有不同的运行时实现,并且它们的数据结构具有不兼容的内部布局。 You can't pass an STL container created in a function compiled by one version of Visual C++ to a function compiled with a different version. 您不能将在由Visual C ++一个版本编译的函数中创建的STL容器传递给使用其他版本编译的函数。 You can't allocate memory with malloc in an executable and free it in a DLL, if the executable and DLL use different versions of the C runtime. 如果可执行文件和DLL使用不同版本的C运行时,则无法在可执行文件中使用malloc分配内存并将其free在DLL中。

Unfortunately unless you're willing to restrict your users to one particular compiler the easy solution to your problem that you're looking for may not exist. 不幸的是,除非您愿意将用户限制在一个特定的编译器上,否则您所寻找问题的简单解决方案可能不存在。 Note that this is a common solution used by programs that provide plugin support. 请注意,这是提供插件支持的程序使用的常见解决方案。 Pugins need to be compiled the same version of the same compiler that compiled the executable. Pugin文件需要与编译可执行文件的版本相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM