【发布时间】:2014-04-24 13:51:38
【问题描述】:
所以我们有一个公共的 C 头文件(拍摄一切都是 C 可调用的)
//foo.h
#ifndef FOO_H
#define FOO_H
extern "C"
{
struct Foo;
typdef FooHandle Foo*;
FooHandle Foo_init();
int Foo_bar(FooHandle handle);
}
#endif
然后是C++头文件:
//foo.hpp
#ifndef FOO_HPP
#define FOO_HPP
namespace my_foo
{
class Foo
{
public:
int bar();
};
}
比一个源文件:
//foo.cpp
#include "foo.h"
#include "foo.hpp"
#include <exception>
void my_foo::Foo:bar() {throw std::exception();}
FooHandle Foo_init() { return reinterpret_cast<FooHandle>(new my_foo::Foo());}
int Foo_bar(FooHandle handle){
my_foo::Foo& foo = *reinterpret_cast<my_foo::Foo*>(handle);
foo.bar();
}
当我在各种平台上从纯 C 上下文(因为不允许 C++ 异常)调用 Foo_bar 时会发生什么?我知道这种行为可能是“未定义的”,但我对各种平台上发生的事情很感兴趣。
【问题讨论】:
-
是的,它是未定义的。我不太明白为什么收集不同平台如何实现特定形式的未定义行为的数据会很有趣。最有可能的是:要么程序崩溃并烧毁,要么什么都不会发生。为什么不运行程序并亲自查看?
-
@Lundin 我正在尝试建立一个反对在这种情况下使用异常的论点......这更像是“如果有人知道那会很棒”,但我不认为任何我们有时间在一堆不同的系统上构建它,看看会发生什么。
-
@MadScienceDreams 我认为没有人知道不同的 UB 在不同系统上的表现方式,因为这不是标准化的。我认为甚至不可能知道。那里没有什么是确定的,所以没有人可以肯定地预测任何事情。即使 99% 的情况发生了什么事,也可能会一时兴起。
-
如果您的 C 代码需要调用利用异常的 C++ 代码,那么您需要在两者之间设置一个粘合层,该层将捕获/屏蔽/忽略/解决任何实际发生的异常,然后再返回可用的内容到 C 代码。从标准的角度来看,它可能仍然是“未定义的行为”,但至少它将是“可预测的”“行为合理的”“未定义的行为”
-
@twalberg 我想这就是我要说的......结合“无法保证代码会以任何方式始终如一地表现”。