问题标签 [implementation-defined-behavior]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - C 中实现定义的行为
请问,您能否报告一些 C 中实现定义的行为的示例?
例如,我从标准中知道“实现定义的行为是有符号整数右移时高位的传播”。
你能给我解释一下这个例子的意义并举个例子吗?
我明白了int i; i >> 3
。但是为什么这是实现定义的呢?
c - C11, 6.6.10:IB:其他形式的常量表达式:需要额外的一致性文档
为什么 C 编译器供应商通常不向最终用户提供关于“其他形式的常量表达式”(C11,6.6.10)的实现定义行为的附加一致性文档(似乎是这样)?
C11,6.6.10:
一个实现可以接受其他形式的常量表达式。
这一事实导致以下反应/反馈(取自不同来源):
SO用户MM:
编译器供应商应该发布一致性文档,列出它接受哪些表达式作为常量,尽管我找不到 MSVC 的文档。(如果可以,请发表评论!)
来源:https ://stackoverflow.com/a/62161678/9881330
SO用户基思汤普森:
诚然,该标准似乎不需要这样的文档(我觉得这有点令人惊讶)。
来源:https ://gcc.gnu.org/bugzilla/show_bug.cgi?id= 66618(2015-07-01 00:48:48 UTC)
由于6.6.10
与实现定义的行为有关,并且由于“每个实现都应包括描述其特征和行为的文档”(C++ 标准,第 1.9 节),为什么在6.6.10
? 如果这里有人代表任何(工业)C 编译器供应商,请提供原因/评论情况。
PS 问题的根源是与«其他形式的常量表达式»相关的可能的可移植性问题。如果最终用户在编写代码之前(而不是之后,对可移植性问题感到惊讶)确切地知道哪些“其他形式的常量表达式”被“实现接受”,将会节省很多时间。
UPD。关于«在使用实现定义的行为时,我会假设存在可移植性问题,除非另有证明»。如果一个软件产品计划在 N 个编译器之间移植,并且所有 N 个编译器都支持相同的 IB 相关语言特性,这在编写代码时很有用,但考虑到实现定义的行为,那为什么不使用它呢?唯一的问题是我们需要提前知道所有N个编译器都支持这个IB相关的语言特性。(是的,我们可以凭经验/实验找到它,但如果有许多与 IB 相关的语言功能,这可能会很耗时。最好有编译器供应商的官方声明,支持此 IB 相关的语言功能/ 不支持。)
c++ - 保留时通过实现定义的因素强制增加向量容量
所以我有一个类包装了一个向量,该向量具有不变量,vec.capacity() > vec.size()
因此我可以始终(临时)emplace_back 再分配一个元素而无需重新分配。我的第一个想法是调用vec.reserve(vec.size() + 1)
每个插入,但正如在这个 stackoverflow 线程中看到的那样,这是低效的,并且插入经常被调用。(pop_back也是如此,因此元素的最大数量远低于插入调用的数量。)
我当前的简化实现看起来像这样:
根据实现定义的策略,是否有一种不太尴尬的方式来触发向量的容量扩展?请注意,T不一定是默认可构造的。
c - 索引“unsigned long”变量并打印结果
昨天,有人给我看了这段代码:
这导致:
我很困惑,主要是for
循环中的行。据我所知,似乎&foo
被转换为 anunsigned char *
然后被i
. 我认为这*(((unsigned char *) &foo) + i)
是一种更冗长的写作方式,((unsigned char *) &foo)[i]
但这看起来像是正在被索引。如果是这样,为什么?循环的其余部分似乎是典型的打印数组的所有元素,所以一切似乎都表明这是真的。演员阵容让我更加困惑。我尝试在 google 上专门搜索有关将整数类型转换为的内容,但在一些关于转换为、等的无用搜索结果专门打印出来后,我的研究陷入了困境foo
unsigned long
unsigned char *
char *
int
char
itoa()
506097522914230528
0 1 2 3 4 5 6 7
,但其他数字似乎在输出中显示了自己唯一的 8 个数字,并且更大的数字似乎填充了更多的零。
c - 是否存在 %p 格式说明符不会以 0x.. 格式打印地址的情况
在 C 中,我从控制台读取地址并将其存储在变量中。我需要以十六进制(0x ...)格式记录地址。
我有两个选择:
- %p
- %X
我已经尝试过选项 2 (%x)。它在 32 位和 64 位平台上的工作方式不同。这导致程序行为不准确。
现在第二个选项 (%p) 也是实现定义的。
所以我想知道应该使用哪一个来在所有编译器和平台上保持一致的行为。
c - 有符号整数溢出未定义行为或实现是否已定义?
我定义了这个 UB 还是实现?
链接说它的UB
https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Integer-Overflow-Basics
链接说它的实现定义
转换规则说:
否则,新类型是有符号的,值不能在其中表示;结果是实现定义的,或者引发了实现定义的信号。
我们不是将 a 转换max unsigned value
为 asigned value
吗?
我所看到的方式,gcc 只是截断了结果。
c - 条件包含:字符常量的数值:在#if/#elif 内与没有#if/#elif:为什么匹配是实现定义的?
案例 A:C11,6.6 常量表达式,语义,5:
如果在翻译环境中计算浮动表达式,则算术范围和精度应至少与在执行环境中计算表达式一样大。116)
这需要以下程序返回 0:
案例 B:C11,6.10.1 条件包含,语义,4:
这些字符常量的数值是否与表达式中出现相同字符常量时获得的值相匹配(除了在#if 或#elif 指令中)是实现定义的。168)
它不需要以下程序返回 0:
问题:制作“案例 B”实现定义的行为的基本原理是什么?
c++ - 超出范围时转换为有符号类型行为
当源值不能在目标类型中表示时将整数转换为有符号类型是根据cppreference
- 实现定义(C++20 前)
- 目标类型的唯一值等于源值模 2^n ,其中 n 是用于表示目标类型的位数 (C++20 起)
同样在GCC实现定义的行为中指定,有
为了转换为宽度为 N 的类型,该值以2^N为模减少到该类型的范围内;没有发出信号。
我想有人说同样的话。我的问题是减少/模数的结果是否仍然可能超出目标签名类型的范围?说signed char c = 255
,255 模 2^8 仍然是 255,不变。这个模数结果如何适合目标类型?
此答案显示了一种首先反转值并加 1,然后添加有符号位的方法。我不确定这是否是实际所做的。
解释强调部分的正确/标准方法是什么?