问题标签 [language-lawyer]
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 语言中未指定行为的一个示例是函数参数的求值顺序。它可能是从左到右或从右到左,你只是不知道。这将影响评估方式foo(c++, c)
或foo(++c, c)
评估方式。
还有哪些其他未指明的行为会让不知情的程序员感到惊讶?
c++ - C++0x 的哪些特性将保持不变(如果有的话)?
C++0x 中是否有任何已知的特性?就像,也许,标准库中的线程?
c++ - 通过下标获取一个过去的数组元素的地址:C++ 标准是否合法?
我已经看到它多次断言 C++ 标准不允许以下代码:
在这种情况下是&array[5]
合法的 C++ 代码吗?
如果可能的话,我想要一个参考标准的答案。
知道它是否符合 C 标准也会很有趣。如果它不是标准的 C++,为什么决定将它与array + 5
or区别对待&array[4] + 1
?
c - C 编译器内部如何处理数组和指针类型?( int *a; 与 int a[]; )
我需要一位有权威来源的语言律师。
看看下面在 gcc 下编译干净的测试程序:
它产生我期望的输出:
a 和 b 是同一类型吗?被处理为与编译器内部 int *a
相同的类型?int a[]
从实际的角度来看,int a[100], b[500], *a_p, b_a[];
所有这些似乎都是同一类型。在我上面的例子中,我很难相信编译器会在各种情况下不断地调整这些类型。我很高兴被证明是错误的。
有人可以明确详细地为我解决这个问题吗?
c++ - 难以置信的快速 C++ 委托和不同的翻译单元
根据 Sergey Ryazanov 的说法,他的Impossibly Fast C++ Delegates没有可比性:
我的代表无法比较。未定义比较运算符,因为委托不包含指向方法的指针。指向存根函数的指针在不同的编译单元中可能不同。
读者回复了哪一位:
“指向存根函数的指针在不同的编译单元中可能不同。” AFAIK,这不是真的。编译器需要重用在不同编译单元中生成的模板函数(我确信这一点——但我认为 Borland 曾经违反过这条规则)。我认为这是因为类(不在“无名”命名空间中的类)使用外部链接,并且您使用存根函数的方式将始终阻止它们被内联(尽管这不应该成为获取函数地址的问题将强制生成一个非内联版本,并且链接器执行的“外部链接”将消除除一个类似命名的函数之外的所有函数(标准假定并要求它们相同))...
如果您在一个翻译单元(cpp 文件)中定义模板函数,然后在另一个翻译单元中以不同方式定义相同的函数,则只有两个版本中的一个会使其成为最终的可执行文件。(这实际上违反了“一个定义规则”,但适用于 GCC,至少......不确定 MSVC。)关键是:[存根的]地址在不同的单元中是相同的。
如果您发现这对于 MSVC 是正确的,我会敦促您更新文章(包括比较功能) - 如果 MSVC 是标准授予,在这方面。
现在这篇文章已经四年了,作者在过去三年左右没有回复任何评论,所以我想知道上述评论是否有任何优点,是否确实可以将这个具体实现更改为支持对比。
C++ 标准是否明确禁止这种用法,如果是,那么最近的编译器在这方面是否真正符合标准?
c++ - 空的大小是多少?
这个陈述会产生什么?
编辑:问题的扩展。
如果 sizeof(void) 在 GCC 编译器中产生 1,则分配 1 个字节的内存并且指针 p 指向该字节并且 p++ 会递增到 0x2346?假设 p 是 0x2345。我说的是 p 而不是 *p。
c++ - 通过 void* 进行投射,而不是使用 reinterpret_cast
我正在读一本书,我发现reinterpret_cast
不应该直接使用它,而是将其转换为 void* 并结合static_cast
:
代替:
但是,我找不到解释为什么这比直接演员更好。如果有人能给我一个解释或指出我的答案,我将不胜感激。
提前致谢
ps 我知道是干什么reinterpret_cast
用的,但我从来没见过这样用的
c++ - 序列点和偏序
几天前这里有一个关于是否表达的讨论
我 = ++我 + 1
是否调用 UB(未定义行为)。
最后得出的结论是,它调用 UB,因为“i”的值在两个序列点之间变化不止一次。
在同一线程中,我参与了与Johannes Schaub的讨论。据他介绍
i=(i,i++,i)+1 ------ (1) /* 也调用 UB */
我说 (1) 不会调用 UB,因为前面的子表达式的副作用被 i 和 i++ 之间以及 i++ 和 i 之间的逗号运算符 ',' 清除。
然后他给出了以下解释:
“是的,在 i++ 之后的序列点完成了它之前的所有副作用,但是没有什么可以阻止赋值副作用与 i++ 的副作用重叠。根本问题是赋值的副作用没有指定在之后发生或在评估赋值的两个操作数之前,因此序列点在保护这个方面无能为力:序列点导致偏序:仅仅因为在 i++ 之后和之前有一个序列点并不意味着所有副作用都是有序的关于 i。
另外,请注意,仅仅一个序列点没有任何意义:评估的顺序不是由代码的形式决定的。它由语义规则决定。在这种情况下,没有语义规则来说明何时发生赋值副作用,以评估其操作数或这些操作数的子表达式”。
用“粗体”写的声明使我感到困惑。我所知道的:
“在被称为序列点的执行序列中的某些指定点,之前评估的所有副作用都应该是完整的,并且后续评估的副作用应该没有发生。”
因为,逗号运算符还指定执行顺序,所以当我们到达最后一个 i.He(Johannes) 时,i++ 的副作用已被取消)。
所以我只想知道(1)是否调用UB?。有人可以给出另一个有效的解释吗?
谢谢!
c++ - 抑制 C++ 中未使用的变量警告 => 编译器错误或代码错误?
目前,我正在使用以下函数模板来抑制未使用的变量警告:
但是,当从 Linux 移植到 cygwin 时,我现在在 g++ 3.4.4 上遇到编译器错误(在 linux 上我是 3.4.6,所以也许这是一个错误修复?):
未使用的参数是一个成员变量,声明为:
这是编译器错误还是我的代码中的错误?
这是最小的测试用例:
c - C 的 main() 函数的有效签名是什么?
C 中 main 函数的有效签名到底是什么?我知道:
还有其他有效的吗?