Tag: 语言律师

用户定义的文字是否允许C ++ 14位分隔符?

当clang编译以下代码时,g ++ 6.1会抱怨数字分隔符(请参阅Coliru上的实例 ): auto time = 01'23s; 哪个编译器(如果有的话)根据C ++ 14标准(N3796)是正确的? 否则,允许数字分隔符(§2.14.2)只是<chrono> chrono <chrono>库(§20.12.5.8)的用户定义文字(§2.14.8)中的实现细节? 恕我直言,它应该不是,因为这些文字是在unsigned long long参数上定义的。 我记得霍华德· 10'000s (Howard 10'000s在他的2016年CppCon演讲“A <chrono>年代<chrono>教程” (约42分钟的演讲)中以10'000s为例。 (请注意,我并不打算编码“1分23秒”,这只是偶然的 ,因为八进制文字0123是64 + 16 + 3 == 83。为了这个目的,我应该写 auto time = 1min + 23s; 但是这种可能的误导性解释不是问题的一部分。)

std :: string总是以C ++ 11为空终止?

Herb Sutter在他的网站2008年的一篇文章中指出: 有一个积极的build议,在C ++ 0x中进一步收紧,并要求空终止,并可能禁止写入时复制的实现,为并发相关的原因。 以下是论文: http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2534.html 。 我认为本文中的一个或两个提案很可能会被采纳,但是我们将在下一次或两次会议上看到。 我知道C ++ 11现在可以保证std :: string的内容是连续存储的,但是他们是否在最后的草稿中采用了上面的内容? 现在是否可以安全地使用像&str[0]这样的东西?

C / C ++在最短的执行时间内提供任何保证吗?

为什么编译器似乎对没有任何作用的循环有礼貌,而不是消除它们? C标准是否需要循环才能花费一些时间? 例如下面的代码: void foo(void) { while(1) { for(int k = 0; k < 1000000000; ++k); printf("Foo\n"); } } 比这个运行速度慢: void foo(void) { while(1) { for(int k = 0; k < 1000; ++k); printf("Foo\n"); } } 即使有-O3优化级别。 我希望删除允许的空循环,从而在两个代码上获得相同的速度。 “花费的时间”是一个应该由编译器保存的副作用吗?

为什么创build了register关键字?

在阅读Herb Sutter的 关键词“不是(或者 别名 )”的时候 ,我遇到了这样几句话: 没错,有些关键字在语义上等同于空白,一个美化的评论。 和 我们已经看到了为什么C ++语言把关键字当作保留字,并且我们看到了两个关键字-auto和register–它们与C ++程序没有任何语义上的区别。 不要使用它们; 无论如何,它们只是空白的,有更快的方法来input空格。 如果像auto这样的关键字(可能不在C ++ 11中)和register是没有价值的,那他们为什么创build和使用? 如果在variables之前包含register没有任何区别 #include<stdio.h> int main(){ register int a = 15; printf("%d\n%d\n",&a,a); return 0; } 为什么上面的程序出错? test_register.c:在函数'main'中: test_register.c:4:2:错误:请求寄存器variables'a'的地址 的printf( “%d \ n%d \ n”,&A,A); 以下程序在C ++中工作。 #include<iostream> int main(){ register int a = 15; std::cout<<&a<<'\n'<<a; return 0; }

编译器降低程序的时间复杂性是否合法? 这是否被认为是可观察的行为?

( 注:这是一个语言律师的问题;我不是指任何特定的现有编译器。 ) 如果有的话,是否允许编译器降低程序的时间复杂度? 在什么情况下(如果有的话),这被认为是“可观察到的行为”,为什么呢? (例如,编译器能否合法地将多项式时间程序“缩减”到指数时间程序?) 如果答案在C和C ++中或在不同的版本中有所不同,请解释它们之间的差异。

为什么仍然需要在使用语句的RHS中用typename来消歧一个依赖types?

我很清楚为什么需要为依赖types使用typename ,因为编译器可能无法在types和variables声明之间消除歧义,当它看到像T::type这样的东西时,请参阅这个答案,以获得很好的解释。 TL; DR :在像T::type * x;这样的expression式中T::type * x; ,编译器不能“知道” T::type是一个types,还是T一些特定的专门化中声明的variables。 然而,在类似的东西 using type = T::type; 没有什么暧昧的。 IMO, T::type 应该总是被parsing为一个types ,因为它是using语句的RHS的一部分。 但是,我们仍然需要在这里使用typename (至less根据gcc和clang) using type = typename T::type; 住在Coliru,gcc 住在Coliru,铛 Visual C ++ 似乎接受没有types名称的代码 ,但我没有太多的信心,编译器完全符合标准(事实上,它有许多非标准的扩展,例如绑定右值到非const引用)。 问题 :为什么这不是C ++ 11及更高版本中的typename规则的例外?

使用switch语句没有大括号是否有用?

在H&S5中,我遇到了不使用大括号的“最离奇的”switch语句(8.7.1,p.277)。 这里是示例: switch (x) default: if (prime(x)) case 2: case 3: case 5: case 7: process_prime(x); else case 4: case 6: case 8: case 9: case 10: process_composite(x); 这个想法似乎是为了避免最常见的小数字prime(x)的开销。 当我看到这个声明时,我对迷失的大括号感到困惑,但是检查官方语法( C1X pre-standard ,6.8.4, p.147 ),语法是正确的:switch语句在switchexpression式后面有一个语句和右括号。 但是在我的编程实践中,我再也没有遇到过这样一个奇怪的switch语句(我不想看到任何我需要负责的代码),但是我开始想: 你们中的任何一个人是否会知道这样一个转换expression式,一个没有使用大括号,但仍然有意义? 不只是switch (i); (这是合法的,但一个NOP),但至less使用两个具有某种有用的目的的案例标签?

设置int的所有字节为(无符号字符)0,保证表示零?

这不是build议的做法 (也不是未定义的行为 )的问题,而是关于将整数types的所有字节转换为(unsigned char)0值的c ++标准实际保证的内容。 问题(S) 在下面的代码片段中, if语句使用的expression式保证在c ++ 11中被评估为true ? std::memset ( reinterpret_cast<char*> (&a), // int a; (unsigned char)0, sizeof (int) ); if (a == 0) { … } 通过阅读C99和C ++ 11标准(本文后面的部分)的引用,我们发现C99明确保证所有位设置为0的整数types将表示该types中的值0 。 我无法在C ++ 11标准中find这个保证。 有没有这样的保证? 前面的代码片段的结果是否是特定于实现的? 在C99(ISO / IEC 9899:1999) 5.2.1.2/1多字节字符 所有位为零的字节应被解释为与移位状态无关的空字符。 这样的字节不应该作为任何其他多字节字符的一部分出现。 6.2.6.2/1整数types 任何填充位的值都是未指定的。 45)符号位为零的有符号整数types的有效(无陷阱)对象表示是相应的无符号types的有效对象表示,并且表示相同的值。 对于任何整数types,所有位都为零的对象表示应该是该types中零值的表示。 在C ++ 11(ISO / IEC […]

重复typedefs – 在C无效,但在C ++有效?

我想要一个标准的引用,为什么下面的代码在C语言中触发了一个符合性警告(使用gcc -pedantic ;“typedef gcc -pedantic ”进行testing),但在C ++( g++ -pedantic )中罚款: typedef struct Foo Foo; typedef struct Foo Foo; int main() { return 0; } 为什么我不能在C中重复定义typedef ? (这对C项目的头结构具有实际意义。)

如果一个枚举无法适合一个无符号整型,会发生什么?

按照Bathsheba的要求,并作为“如果枚举不能整合到一个types中会发生什么?”的后续问题。 : 假设一个枚举定义如下: enum foo : unsigned int { bar = UINT_MAX, oops }; oops的价值是定义的还是不是? MSVS2015编译: warning C4340: 'oops': value wrapped from positive to negative value warning C4309: 'initializing': truncation of constant value warning C4369: 'oops': enumerator value '4294967296' cannot be represented as 'unsigned int', value is '0' MSVS2015输出: bar = 4294967295 oops= 0 gcc […]