Tag: 语言律师

为什么`int;`在C中编译好,但在C ++中编译不好?

考虑以下程序(请参阅此处的实时演示)。 #include <stdio.h> int main(void) { int ; // Missing variable name puts("Surprise"); } 我的编译器,gcc 4.8.1,给出了下面的警告: [Warning]空声明中无用的types名称[默认启用] 为什么编译好? 我不应该得到一个编译器错误? 当我编译为C ++程序时,g ++ 4.8.1给出了以下错误: [错误]声明不声明任何[-fpermissive]

std :: is_unsigned <bool> :: value是否定义良好?

我想知道是否 std::is_unsigned<bool>::value 根据标准是否明确定义? 我问这个问题,因为typename std::make_unsigned<bool>::type没有很好的定义。

为什么派生类移动时可以构build基类不是?

考虑下面的例子: #include <iostream> #include <string> #include <utility> template <typename Base> struct Foo : public Base { using Base::Base; }; struct Bar { Bar(const Bar&) { } Bar(Bar&&) = delete; }; int main() { std::cout << std::is_move_constructible<Bar>::value << std::endl; // NO std::cout << std::is_move_constructible<Foo<Bar>>::value << std::endl; // YES. Why?! } 为什么编译器生成一个移动构造函数,尽pipe基类是不可移动的可构造的? 这是标准还是编译器错误? 是否有可能“完美地宣传”从基地到派生class的build设?

函数返回值的自动对象,从而保证被破坏?

在[except.ctor]标准( N4140 )保证: 自从try块被input后,为所有构造的自动对象调用析构函数… 但是在下面的例子中,空输出certificate了函数foo的返回值没有被破坏,尽pipe它已经被构造了。 使用g ++(5.2.1)和clang ++(3.6.2-1)和选项-O0 -fno-elide-constructors -std=c++14 。 struct A { ~A() { cout << "~A\n"; } }; struct B { ~B() noexcept(false) { throw 0; } }; A foo() { B b; return {}; } int main() { try { foo(); } catch (…) { } } 这是g ++和clang ++中的一个bug,还是函数返回值不被视为自动对象,还是C ++语言中的循环漏洞? […]

是`x = std :: move(x)`undefined?

令x是以前已经初始化的某种types的variables。 是以下行: x = std::move(x) 未定义? 标准在哪里呢?它是怎么说的?

在修改的exception上使用`throw;`

我有一个函数foo可以抛出一个exception。 在另一个函数中,我调用foo但是如果抛出exception,我可以添加一些更多的细节。 (我宁愿不将这样的信息作为parameter passing给foo因为它不属于那个属性,因为这个函数的generics特性。) 所以我在调用者中这样做: try { foo(); } catch (bar& ex){ ex.addSomeMoreInformation(…); throw; } 会throw重新抛出修改的exception还是我需要使用throw ex; ? 后者大概会采取价值副本,所以我宁愿不这样做。 会throw一个有价值的副本吗? 我怀疑它不会。 (我知道我可以validation,但我担心绊倒一个未指定或未定义的结构,所以想知道肯定)。

我们真的需要C ++ 11中的“枚举类”吗?

当我们有, struct E { enum E_ { HELLO }; }; // 'E' is inheritable 那为什么我们需要, enum class E { HELLO }; // 'E' is not inheritable 国际海事组织第二版不提供更多的function比第一。 我不认为引入enum class只是为了节省2个大括号{}; ! 我错过了任何重要的方面? 作为一个小问题,是除了语法之外的enum class和enum struct之间有任何区别(因为都有public访问说明符)?

为什么在for循环中允许任意的目标expression式?

我不小心写了这样的代码: foo = [42] k = {'c': 'd'} for k['z'] in foo: # Huh?? print k 但令我惊讶的是,这不是一个语法错误。 而是打印{'c': 'd', 'z': 42} 。 我的猜测是,代码字面上翻译成类似于: i = iter(foo) while True: try: k['z'] = i.next() # literally translated to assignment; modifies k! print k except StopIteration: break 但是…为什么这是语言所允许的呢? 我期望只有单一的标识符和标识符的元组应该被允许在目标的目标expression式中 。 有没有什么情况下,这实际上是有用的,不只是一个怪异的陷阱?

为什么clang的stdbool.h包含#define false false

在被编译器错误指向之后,我注意到了clang的stdbool.h文件包含(除其他外)以下几行: #define bool bool #define false false #define true true 它们包含在一个#ifdef块中,间接强制__cplusplus ,因此即使stdbool.h是C头,也是c ++标签。 这些定义需要什么? 我想他们是需要一些预处理器相关的原因,但我有兴趣知道标准的哪个部分或哪个技术原因使得它铿锵必须包括这些。

在C和C ++中返回voidtypes

这个编译没有任何警告。 这是合法的C和C + +或只是在gcc和叮当工作? 如果这是合法的,那么C99之后的新事物呢? void f(){ } void f2(){ return f(); } 更新 作为“雷克萨斯”build议我试过这个: $ gcc -Wall -Wpedantic -c xc xc: In function 'f2': xc:7:9: warning: ISO C forbids 'return' with expression, in function returning void [-Wpedantic] return f(); $ clang -Wall -Wpedantic -c xc xc:7:2: warning: void function 'f2' should not return void […]