Questions tagged «language-lawyer»

有关编程语言和环境的正式或权威规范的复杂性的问题。

13
如何制作不会被优化的无限空循环?
C11标准似乎暗示不应优化具有恒定控制表达式的迭代语句。我从这个答案中获取建议,该答案特别引用了标准草案的6.8.5节: 该实现可以假定其控制表达式不是常量表达式...的迭代语句终止。 在该答案中,它提到while(1) ;不应对循环进行优化。 那么...为什么Clang / LLVM优化了下面的循环(与编译cc -O2 -std=c11 test.c -o test)? #include <stdio.h> static void die() { while(1) ; } int main() { printf("begin\n"); die(); printf("unreachable\n"); } 在我的机器上,此打印输出begin,然后在一条非法指令(ud2位于后面的陷阱die())中崩溃。在godbolt上,我们可以看到调用之后什么也没有产生puts。 让Clang在下面输出无限循环是一件非常困难的任务-O2-虽然我可以重复测试一个volatile变量,但该变量涉及不需要的内存读取。如果我做这样的事情: #include <stdio.h> static void die() { while(1) ; } int main() { printf("begin\n"); volatile int x = 1; if(x) die(); …



5
Double的“ ==”运算符的定义
由于某种原因,我偷偷摸摸该类的.NET Framework源代码Double,发现其中的声明==为: public static bool operator ==(Double left, Double right) { return left == right; } 相同的逻辑适用于每个操作员。 这样定义的意义何在? 它是如何工作的? 为什么不创建无限递归?
126 c#  .net  language-lawyer 

2
Lambda捕获和具有相同名称的参数-谁遮蔽了另一个?(c声与gcc)
auto foo = "You're using g++!"; auto compiler_detector = [foo](auto foo) { std::puts(foo); }; compiler_detector("You're using clang++!"); clang ++ 3.6.0及更高版本打印出“您正在使用clang ++!” 并警告捕获 foo未使用。 g ++ 4.9.0及更高版本打印出“您正在使用g ++!” 并警告未使用该参数 foo。 哪种编译器更准确地遵循C ++标准? 魔盒示例

6
Lambda回归自我:这合法吗?
考虑这个相当无用的程序: #include <iostream> int main(int argc, char* argv[]) { int a = 5; auto it = [&](auto self) { return [&](auto b) { std::cout << (a + b) << std::endl; return self(self); }; }; it(it)(4)(6)(42)(77)(999); } 基本上,我们试图制作一个返回自身的lambda。 MSVC编译程序,然后运行 gcc编译程序,并进行段错误 clang拒绝该程序并显示一条消息: error: function 'operator()<(lambda at lam.cpp:6:13)>' with deduced return type cannot …

3
是否使用if(0)跳过应该起作用的开关中的情况?
我有一种情况,我希望C ++ switch语句中的两种情况都落入第三种情况。具体而言,第二种情况将落入第三种情况,并且第一种情况也将落入第三种情况而不会通过第二种情况。 我有一个愚蠢的想法,尝试了一下,就成功了!我把第二个盒子包裹在一个if (0) {...中}。看起来像这样: #ifdef __cplusplus # include <cstdio> #else # include <stdio.h> #endif int main(void) { for (int i = 0; i < 3; i++) { printf("%d: ", i); switch (i) { case 0: putchar('a'); // @fallthrough@ if (0) { // fall past all of case 1 …

2
什么时候在空实例上调用成员函数会导致未定义的行为?
考虑以下代码: #include <iostream> struct foo { // (a): void bar() { std::cout << "gman was here" << std::endl; } // (b): void baz() { x = 5; } int x; }; int main() { foo* f = 0; f->bar(); // (a) f->baz(); // (b) } 我们预期(b)会崩溃,因为xnull指针没有对应的成员。实际上,(a)不会崩溃,因为this从未使用过指针。 因为(b)取消引用this指针((*this).x = 5;),并且this为null,所以程序将输入未定义的行为,因为始终将取消引用null视为未定义的行为。 会(a)导致不确定的行为吗?如果两个函数(和x)都是静态的怎么办?

5
为什么在真实情况下带逗号的三元运算符只求一个表达式?
我目前正在使用C ++ Primer一书学习C ++,这本书中的练习之一是: 说明以下表达式的作用: someValue ? ++x, ++y : --x, --y 我们知道什么?我们知道,三元运算符的优先级高于逗号运算符。对于二元运算符,这很容易理解,但是对于三元运算符,我有点挣扎。对于二进制运算符,“具有更高的优先级”意味着我们可以在具有更高优先级的表达式周围使用括号,并且不会更改执行。 对于三元运算符,我将执行以下操作: (someValue ? ++x, ++y : --x, --y) 有效地产生相同的代码,这无助于我理解编译器如何对代码进行分组。 但是,通过使用C ++编译器进行测试,我知道表达式可以编译,而且我不知道:运算符本身可以代表什么。因此,编译器似乎正确地解释了三元运算符。 然后,我通过两种方式执行该程序: #include <iostream> int main() { bool someValue = true; int x = 10, y = 10; someValue ? ++x, ++y : --x, --y; std::cout << …

2
在3种主要的C ++编译器中,程序进行了不同的编译。哪一个是对的?
作为对我之前的问题的有趣的跟进(尽管不是很重要), 为什么在声明变量时C ++为什么允许我们在括号中将变量名括起来? 我发现将括号中的声明与注入的类名功能结合使用可能会导致有关编译器行为的令人惊讶的结果。 看一下以下程序: #include <iostream> struct B { }; struct C { C (){ std::cout << "C" << '\n'; } C (B *) { std::cout << "C (B *)" << '\n';} }; B *y = nullptr; int main() { C::C (y); } 使用g ++ 4.9.2进行编译会给我以下编译错误: main.cpp:16:10: error: cannot …

8
在C ++中使用C标头时,我们应该使用std ::或全局名称空间中的函数吗?
C在某种程度上,也不完全是C ++的子集。因此,我们可以通过改变名称一点点(使用最多的C函数的C /头++ stdio.h来cstdio,stdlib.h到cstdlib)。 我的问题实际上是一种语义。在C ++代码(使用最新版本的GCC编译器)中,我可以调用printf("Hello world!");和std::printf("Hello world!");,它的工作原理完全相同。在我正在使用的参考资料中,它也显示为std::printf("Hello world!");。 我的问题是,是否首选std::printf();在C ++中使用?有区别吗?
113 c++  language-lawyer  std 

8
什么是“回调地狱”,RX如何以及为什么解决它?
有人可以给出一个清晰的定义,以及一个简单的示例,为不懂JavaScript和node.js的人解释什么是“回调地狱”吗? 什么时候(以哪种设置)发生“回调地狱问题”? 为什么会发生? “回调地狱”是否总是与异步计算相关? 还是在单线程应用程序中也可能发生“回调地狱”? 我在Coursera参加了“反应式课程”,Erik Meijer在他的一次演讲中说RX解决了“回调地狱”的问题。我在Coursera论坛上问什么是“回调地狱”,但我没有明确的答案。 在一个简单的示例上解释了“回调地狱”之后,您还可以说明该简单示例上的RX如何解决“回调地狱问题”吗?

2
C ++ 20是否要求将源代码存储在文件中?
但是,一个有点奇怪的问题是,如果我没记错的话,C ++源代码不需要文件系统来存储其文件。 拥有一个可以通过相机扫描手写纸的编译器将是一个符合要求的实现。尽管实际上没有太大意义。 但是,C ++ 20现在使用添加了源位置file_name。现在,这是否意味着源代码应始终存储在文件中?

9
使用新的标准版本的C ++中是否有过无声的行为更改?
(我正在寻找一个或两个例子来证明这一点,而不是清单。) 是否曾经发生过C ++标准的更改(例如从98变为11、11到14等)以无声的方式改变了现有的,格式正确的,定义了行为的用户代码的行为?即在使用较新的标准版本进行编译时没有警告或错误? 笔记: 我问的是标准规定的行为,而不是实现者/编译器作者的选择。 编写的代码越少越好(作为对此问题的答案)。 我并不是说带有版本检测功能的代码,例如#if __cplusplus >= 201103L。 涉及内存模型的答案很好。

2
有效最终与最终-不同的行为
到目前为止,我认为有效的final和final或多或少是等效的,并且JLS将在实际行为上将它们视为相同或相似的内容。然后我发现了这个人为的场景: final int a = 97; System.out.println(true ? a : 'c'); // outputs a // versus int a = 97; System.out.println(true ? a : 'c'); // outputs 97 显然,JLS在这两者之间起了重要的作用,我不确定为什么。 我读了其他主题 最终和有效最终之间的区别 有效的最终变量与最终变量 变量“有效最终”是什么意思? 但它们没有详细说明。毕竟,从更广泛的意义上讲,它们似乎是等效的。但是深入研究,它们显然有所不同。 是什么导致此行为,任何人都可以提供一些解释此问题的JLS定义吗? 编辑:我发现了另一个相关的方案: final String a = "a"; System.out.println(a + "b" == "ab"); // outputs true // …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.