更新2016-12 此行为现在还有一个最小的示例:https://community.nxp.com/message/862676
我正在使用ARM Cortex M4和freertos使用freescales自由Kinetis IDE(gnu arm工具链).问题是
try {
throw 4; // old scenario also not working: throw std::runtime_error("wut");
} catch (...) {
}
Run Code Online (Sandbox Code Playgroud)
在try处理程序之后导致暂停的CPU和代码,或者在catch处理程序中(当添加一些代码时)不会执行.
可以在这里找到汇编:https://gist.github.com/Superlokkus/3c4201893b4c51e154e2a0afdf78fef0
我认为这会导致SVC中断,我很抱歉我弄错了,Freertos欺骗了我,因为当我扔东西时它会在DefaultISR中停止.
throw indeeds跳转到 __cxa_throw然后从那里跳到___Unwind_RaiseException __gnu_Unwind_RaiseException __cxa_begin_catch> <_ZSt9terminatev>
所以它看起来像是std::terminate
被调用,但是catch all块不应该允许这个.或者我的假设是错误的,这种行为是因为gcc C++运行时异常支持是一个总是调用终止的存根?!
更新2016-09:因为我看到rand()尝试使用malloc(),我还定义了一个工作的malloc()/ freeRTOS函数和etvoilà:__ cxa_allocate_exception使用malloc(我想知道工具链是如何期望我处理bad_alloc的情况).所以现在,它仍然崩溃,但在异常分配后(我认为):执行路径是:
(throwing function after exception allocation)
__cxa_throw
... //(some intructions in __cxa_throw)
__cxa_begin_catch //I guess something went wrong here
_ZSt9terminatev // Immediately after __cxa_begin_catch
_ZN10__cxxabiv111__terminateEPFvvE:
00016dfc: push {r3, lr}
00016dfe: blx r0 //Goes …
Run Code Online (Sandbox Code Playgroud) 我知道这是自行车脱落,但有一种方式来获得一组琴弦C,两者之间(分类)设置,字符串,其中B是A的子串,具有复杂性比的更好的说明B A.size * B.size * comp_substr
,作为幼稚解决方案我来了吗?
std::copy_if(devices.cbegin(), devices.cend(),
std::back_inserter(ports),
[&comport_keys] (const auto& v) {
return std::any_of(comport_keys.begin(),comport_keys.end(), [&v](auto& k) {
return v.find(k) != std::string::npos;
});
});
Run Code Online (Sandbox Code Playgroud)
如果B是A的字符串,则更std::set_intersection
简单的情况是(A.size + B.size) * comp_substr
,如果复杂度为,则将非常简单,如果必须先对其进行排序,则将更好(n * log(n))
,但是我不知道如何为它编写比较函数,或两者兼而有之。
#define BOOST_TEST_MODULE My Test
#include <boost/test/included/unit_test.hpp>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <set>
BOOST_AUTO_TEST_CASE(TEST) {
std::vector<std::string> devices{
"tty1",
"ttyOfk",
"ttyS05",
"bsd",
}, ports{};
const std::set<std::string> comport_keys{
"ttyS",
"ttyO",
"ttyUSB",
"ttyACM",
"ttyGS",
"ttyMI",
"ttymxc",
"ttyAMA",
"ttyTHS",
"ircomm",
"rfcomm",
"tnt", …
Run Code Online (Sandbox Code Playgroud) 当我写了一个关于如何在不包含 cmath 库的情况下使用 pow的答案时,我担心已经证明缺少所需标头的包含实际上是未定义的行为,但是由于我还没有发现任何同意这一事实的事实,我想强加正式问题:
缺少必需的标题,即
#include <iostream>
int main()
{
std::cout << std::pow(10, 2);
}
Run Code Online (Sandbox Code Playgroud)
在我的回答中,我倾向于肯定两个问题,但是 [using.headers] 非常令人困惑,因为未定义行为和格式错误之间的差异,不需要诊断消息。由于 [defns.well.formed] 意味着为 ODR 构建的程序是结构良好的,并且有关于何时iostream
不能定义的规范pow
,人们可能会争辩说这仍然是未指定的行为 ([defns.unspecified])。对于如此重要的问题,我不想仅仅依靠我的标准解释技巧来确定答案。请注意,如果代码是 UB,则接受的即唯一的其他答案不会回答,问题也不会询问它。
我试过但未能得到以下工作std::algorithms
:我有aa std::map<key_t,value_t> cache
和a std::set<key_t> selected_items
我想删除键/值对cache
,除了包含的键selected_items
.
这是我没有算法写的东西:
//This could really be written better with std::algorithms but time...
//Delete old
for (auto pair = cache.begin(); pair != cache.end(); ) {
if (selected_items.find(pair->first) == selected_items.end())
pair = cache.erase(pair);
else
++pair;
}
Run Code Online (Sandbox Code Playgroud)
为了利用算法库,我想我需要使用std::set_difference
比较函数和任何一个std::remove
或std::map::erase
.但我不能连接件,失败的是:
我的代码应该怎么样?
我不确定如何std::istream::exception
根据标准使用,std::istream::operator>>
如果无法将输入读入变量,则抛出异常,例如double.以下代码与clang/libc ++和gcc/libstdc ++有不同的行为:
#include <iostream>
#include <cassert>
int main () {
double foo,bar;
std::istream& is = std::cin;
is.exceptions(std::istream::failbit);
is >> foo; //throws exception as expected with gcc/libstdc++ with input "ASD"
std::cout << foo;
is >> bar;
std::cout << bar;
assert(is); //failed with clang/libc++ after input "ASD"
std::cout << foo << " " << bar << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
根据C++标准,是否is.exceptions(std::istream::failbit);
适合operator>>
抛出目的?
我担心这又是一个关于解释 ISO/IEC 14882(C++ 标准)的问题,但是:
\nmain
是否从程序中调用,例如我至少main()
从实现定义的行为中递归调用?main
(更新:我的意思是稍后格式不正确,未定义实现,也不是 UB,请参见下文并回答)
6.9.3.1 [basic.start.main] 状态
\n\n\n3 程序中不得使用 main 函数。main 的链接 (6.6) 是实现定义的......
\n
共识似乎是未定义行为(UB)。MSVC 的文档也指向 UB,gcc 的文档也隐含地否认实现定义的行为。它不可能是 [defns.unspecified] 未指定的行为,因为我将不解释为格式不正确。
\n然而,尽管有这些实现,根据我的解释,不应该是 UB,而是如 4.1 [intro.compliance] 所示
\n\n\n1 可诊断规则集包含本文档中的所有语法和语义规则,但\n包含明确表示\xe2\x80\x9c 不需要诊断\xe2\x80\x9d 的规则或被描述为导致\n \xe2\x80\x9c 未定义的行为\xe2\x80\x9d。\n...\n(2.2) \xe2\x80\x94 如果程序包含违反任何可诊断规则的行为或出现\n中描述的构造当实现不支持该构造时,文档为 \xe2\x80\x9cconditionally-supported\xe2\x80\x9d,\n 符合要求的实现应发出至少一条诊断消息。
\n
对我来说,推理似乎很清楚
\n我想知道条件语句(例如if语句)的正确用法,以避免未定义的行为。让我们从一个例子开始:
uint8_t x = 0;
bool y = false;
bool z = false;
if ((x == 135) and !y and !z) {
//do something
}
else if ((x == 135) and y) {
x = 5;
z = true;
}
else if ((x == 5) and z) {
x = 135;
z = false;
}
else {
//do something
}
Run Code Online (Sandbox Code Playgroud)
现在,是否通过不将所有3个变量都包含在每个条件中来获得不确定的行为?是否将所有未说明的条件都放入else语句中?如果是这样,如果我放弃else语句会怎样?我有完全相同的if语句(在更复杂的情况下),而且我似乎每次都不会进入正确的语句。
如果有此规定,请赐教。
c++ conditional if-statement undefined-behavior language-lawyer