相关疑难解决方法(0)

如何检查指针是否指向正确对齐的内存位置?

给定void *一些存储,如何检查它是否指向正确对齐的存储而没有任何实现定义的行为?

我们当然有std::align,但是有更有效的方法吗?

template <std::size_t alignment>
inline bool is_aligned(void * ptr) noexcept {
    std::size_t max = 1u;
    return std::align(alignment, 1u, ptr, max);
}
Run Code Online (Sandbox Code Playgroud)

PS:我需要以兼容C++标准的方式执行此操作,而不依赖于任何特定于平台的(实现定义的)黑客攻击.

PPS:我为我(理解)英语而道歉,而不是我的母语.


EDIT(2018.08.24):从标题中删除了"有效",添加了更多的措辞,强调我不希望任何实现定义或特定于平台的行为.

c++ memory-alignment c++11 c++14 c++17

30
推荐指数
1
解决办法
3397
查看次数

未定义行为与错误形成之间的区别,无需诊断消息

C++标准配备的用于定义一个惊人的数不清楚1种,其意味着与细微的差别或多或少相同的行为.读到这个答案后,我注意到"该程序格式错误;无需诊断"的措辞.

实现定义未指定的行为的不同之处在于前一种情况下的实现必须清楚地记录它正在做什么(在后一种情况下,它不需要),两者都是格式良好的.未定义的行为与未指定的行为不同,因为程序是错误的(1.3.13).
否则它们都有一个共同点,就是标准不会对实现的内容做出任何假设或要求.除1.4/8之外,其中声明实现可能具有不会改变格式良好的程序的行为的扩展,但根据标准是不正确的,并且实现必须诊断使用这些,但之后可以继续编译和执行不正当的计划.

一个病态的程序否则只能定义为没有很好地形成(太棒了!).甲合式程序,在另一方面,被定义为一个附着在语法和诊断的语义规则.因此,这意味着错误的程序是打破语法或语义规则(或两者)的程序.换句话说,一个不正确的程序实际上根本不应该编译(如何以任何有意义的方式翻译例如具有错误语法的程序?).

我倾向于认为错误这个词也意味着编译器应该使用错误消息中止构建(毕竟,错误表明存在错误),但1.3.13中的"注意"部分明确允许不同的东西,包括默默地忽略问题(并且编译器显然不会因为UB 破坏构建,大多数甚至不会默认警告).

人们可能会进一步认为错误和不正确的形式是相同的,但如果情况或该词应该是什么意思,那么标准就不会详细说明.

此外,1.4表示

符合要求的实施应[...]接受并正确执行格式良好的程序

如果程序包含违反不需要诊断的规则,则不要求对该程序进行实施.

换句话说,符合要求的实现必须接受格式良好的程序,但它也可能接受形式错误的程序,甚至没有警告.但是,如果程序因为使用扩展而格式不正确.

第二段建议任何与"无需诊断"相关的内容意味着规范中没有要求,这意味着它大部分等同于"未定义的行为",除非没有提到错误.

因此,使用"形成不良;无需诊断"等措辞背后的意图是什么?

"无诊断"的存在表明它与未定义的行为完全相同(或大部分相同?).此外,由于实现定义未指定的行为被定义为格式良好,因此它必须是不同的.

另一方面,由于格式错误的程序会破坏语法/语义规则,因此它实际上不应该编译.但是,与"不需要诊断"相结合意味着允许编译器在没有警告的情况下以静默方式退出,并且之后您将无法找到可执行文件.

"形成不良;无需诊断"和"未定义行为"之间是否存在差异,或者这只是同一事物的复杂同义词?


1对行为集体缺乏更好的措辞

c++ undefined-behavior language-lawyer

23
推荐指数
2
解决办法
3409
查看次数

根据标准,不正确的程序需要什么C++编译器?

C++ 03 Standard将格式良好的程序(1.3.14 [defns.well.formed])定义为

根据语法规则,可诊断的语义规则和一个定义规则(3.2)构建的C++程序

它进一步定义了一个不正常的程序(1.3.4 [defns.ill.formed])as

输入到不是格式良好的程序的C++实现(1.3.14)

并且标准中充满了诸如"如果X那么程序是格式错误"的陈述,例如(2.13.1/3):

如果某个程序的翻译单元中包含一个无法用任何允许类型表示的整数文字,则该程序格式不正确.

然而,我还没有找到C++实现对于格式错误的程序需要做些什么.

假设我有一个不正确的程序.怎么办?

C++实现是否需要在遇到格式错误的程序时执行某些特定操作,或者C++实现行为是否未定义?

c++ compiler-construction language-lawyer

21
推荐指数
2
解决办法
1734
查看次数

"无需诊断"的理由是什么?

大多数人都熟悉C++中的"未定义"和"未指定"的行为记录,但是"不需要诊断"呢?

我注意到这个问题和答案,涉及形成不良的程序,但没有详细说明"无需诊断"声明的根源.

委员会在将某些内容归类为"无需诊断"时采用的一般方法是什么?

  • 标准委员会指定错误的错误有多严重?
  • 这些错误是否几乎不可能被发现,因此诊断?

"未定义"和"未指定"行为的例子并非短缺; 在没有ODR的情况下,"无需诊断"类型错误有哪些实际例子?

c++ language-lawyer c++11

14
推荐指数
2
解决办法
1061
查看次数

成功编译不良程序是否符合标准?

对于一个不正确的C++程序,如:

foo^@#$bar%$
Run Code Online (Sandbox Code Playgroud)

编译器是否符合标准,以产生带有诊断消息的编译二进制文件,而不是像g ++/clang ++那样中断编译?

intro.compliance声明:

如果程序包含违反任何可诊断规则或本标准中描述的构造的发生,如果实现不支持该构造,则符合条件的实现应发出至少一条诊断消息.

在这种情况下不需要编译错误.

可能相关:

c++ language-lawyer

2
推荐指数
1
解决办法
87
查看次数