如何在不包含Windows.h的情况下获取DebugBreak的声明? 我们有一个C++库。我们提供了一个自定义断言,并放弃了PosixNDEBUG和assert(背景故事如下)

如何在不包含Windows.h的情况下获取DebugBreak的声明? 我们有一个C++库。我们提供了一个自定义断言,并放弃了PosixNDEBUG和assert(背景故事如下),c++,windows,visual-studio,assert,C++,Windows,Visual Studio,Assert,在Windows下,断言看起来是这样的: # define CRYPTOPP_ASSERT(exp) { \ if (!(exp)) { \ std::ostringstream oss; \ oss << "Asser

在Windows下,断言看起来是这样的:

#  define CRYPTOPP_ASSERT(exp) {                                  \
    if (!(exp)) {                                                 \
      std::ostringstream oss;                                     \
      oss << "Assertion failed: " << (char*)(__FILE__) << "("     \
          << (int)(__LINE__) << "): " << (char*)(__FUNCTION__)    \
          << std::endl;                                           \
      std::cerr << oss.str();                                     \
      DebugBreak();                                               \
    }                                                             \
  }
下面是使用extern声明模拟用户程序时出现的错误。此测试发生在安装了VS2012和VS2013的Windows 8.1 x64上。我们还使用了开发人员命令提示符

Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

assert.cpp
assert.cpp(11) : warning C4273: 'DebugBreak' : inconsistent dll linkage
        C:\Program Files (x86)\Windows Kits\8.1\include\um\debugapi.h(70) : see
previous definition of 'DebugBreak'
assert.cpp(21) : error C2589: '(' : illegal token on right side of '::'
assert.cpp(21) : error C2059: syntax error : '::'
assert.cpp(21) : error C2143: syntax error : missing ';' before '{'
当我们检查
时,我们看到:

WINBASEAPI
VOID
WINAPI
DebugBreak(
    VOID
    );
WINBASEAPI
扩展为其他宏。我认为我们不可能在所有平台上都让它们正常运行


我们有一个跨平台的C++安全库,最近被捕获了。由于触发断言可能导致数据丢失,因此被归类为信息披露。当敏感数据被导出到文件系统(核心转储和崩溃报告)时发生丢失;并转给第三方(苹果通过CrashReporter、Ubuntu通过Apport、微软通过Windows错误报告、开发者等)

由于我们的Makefile和VisualStudio解决方案很好地配置了库,所以在我们的生产/发行版中从未触发过断言。在生产/发布构建中,断言被删除,C++(代码)> SUBER()/Cux>处理错误条件。断言存在于调试/开发人员配置中,因此代码将自行调试,并将程序员从任务中解脱出来


经过分析,我们意识到。人们不会阅读文档;如果RTFM能够工作,那么它现在就已经发生了。此外,CMake不会定义它,Autotools不会定义它,Eclipse不会定义它,等等。我们实际上处于CVE之前的同一点。我们所做的只是在不降低风险的情况下推卸责任。

您可以使用内在的,它不包括:

__debugbreak();

如果您使用
\uu stdcall
extern“C”
进行声明,那么使用Visual Studio 6和2015声明
DebugBreak
似乎可以正常工作。由于VC++6似乎没有在算法头中包含
std::min
,我对您的示例进行了一些修改,但是如果第一个参数大于第二个参数,则在使用
cl-nologo-W3-O2-Zi-NDEBUG-o assert.exe assert.cpp-link-subsystem:console-debug构建时会引发断言

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

extern "C" extern void __stdcall DebugBreak(void );

#define MY_ASSERT(exp) { \
   if (!(exp)) {         \
     DebugBreak();       \
   }                     \
}

void dummy(int x1, int x2)
{
    MY_ASSERT(x1 < x2);
}

int main(int argc, char *argv[])
{
    if (argc != 3) {
        fprintf(stderr, "usage: assert integer integer\n");
        exit(1);
    }
    int a = strtol(argv[1], NULL, 0);
    int b = strtol(argv[2], NULL, 0);
    dummy(a, b);
    return 0;
}
#包括
#包括
#包括
外部“C”外部无效uu stdcall DebugBreak(无效);
#定义我的断言(exp){\
如果(!(exp)){\
DebugBreak()\
}                     \
}
无效虚拟(int-x1,int-x2)
{
我的断言(x1
只需添加一个新的源代码文件,其中只包含:

#include <windows.h>

void MyDebugBreak(void)
{
   DebugBreak();
}
#包括
void MyDebugBreak(void)
{
DebugBreak();
}
根据需要导出,并在宏中调用MyDebugBreak()而不是DebugBreak()


您可以仅在Windows版本中包含该文件,也可以在适当的情况下添加
#
块。

很抱歉,您需要它,但您是否有?如果你有,我会调查的。当我只想让结构测量准确的时间并将其整理出来时,
定义真假和破坏性的东西时,我遇到了这个问题。代码调试的步骤:1)读取它,2)记录它,3)逐步完成它,4)设置陷阱5)为客户设置陷阱(在发布版本中)。@Jean Françoisfare-足够公平。“一些额外的CRUFT,如<代码> MIN <代码>和 max ,打断C++编译。”——这就是为什么“代码> >定义NoMnmax < /Cuth>。可以驯服Windows头文件。我不是建议你走这条路,但如果你必须这样做的话,这很有可能。@IInspectable-请发布使用
NOMINMAX
的代码,这样它就不会从我们的头中交叉传播到用户头中。我很乐意测试。谢谢@patthoyts。不幸的是,
extern“C”
由于不同的链接导致相同的编译错误。我还添加了来自
DebugBreak
的Microsoft签名。他们似乎用比他们记录的更多的东西来装饰这个符号。谢谢@Harry。我认为这样可以确保没有异花授粉。我将尝试@Dani的解决方案,因为它是一个只有标题的解决方案,并且:“x86,ARM,x64”。对
的要求不太正确;它打破了VS2002和VS2003。这些好处:“您可以调用DebugBreak Win32函数或_DebugBreak…因为DebugBreak是对系统函数的调用,所以必须安装系统调试符号…”@jww:我唯一关心的是Dani的解决方案是它特定于Visual Studio。如果这在你的上下文中不是一个问题,那么是的,这听起来是最好的选择。测试将揭示它们。在这一点上,MinGW是我唯一关心的,但我没有一个测试平台,尽管我真诚地努力建立了一个。Borland是另一个关注点,但我只知道一个用户使用它。我试图从Embarcadero那里获得免费的测试许可证,但他们拒绝了。因此,他们的用户必须承受痛苦,直到有人提醒我们并提交补丁。
#include <windows.h>

void MyDebugBreak(void)
{
   DebugBreak();
}