Questions tagged «c++»

C ++是一种通用编程语言。它最初被设计为C的扩展,并且具有类似的语法,但是现在它是一种完全不同的语言。使用此标记可解决有关将要使用C ++编译器编译的代码的问题。对于与特定标准修订版[C ++ 11],[C ++ 14],[C ++ 17]或[C ++ 20]等相关的问题,请使用特定于版本的标记。

20
而(1)for(;;)是否存在速度差异?
长版... 一位同事在看到我while (1)在for (;;)更快的Perl脚本中使用后断言。我认为他们应该是一样的,希望解释器可以优化任何差异。我设置了一个脚本,该脚本将为循环迭代和相同数量的while循环运行1,000,000,000,并记录它们之间的时间。我发现没有明显的区别。我的同事说,一位教授告诉他while (1)正在进行比较1 == 1,for (;;)而没有进行比较。我们使用C ++的迭代次数进行了100倍的重复相同的测试,并且差异可以忽略不计。但是,这是一个图形示例,说明了与脚本语言相比,编译后的代码可以提高多少速度。 精简版... 如果您需要无限循环来突破,有什么理由while (1)比a for (;;)优先? 注意:如果问题尚不清楚。这纯粹是几个朋友之间有趣的学术讨论。我知道这不是所有程序员都应该苦恼的超级重要概念。感谢您提供的所有出色答案,我(而且我敢肯定其他人)已经从这次讨论中学到了一些东西。 更新:上述同事在下面进行了回应。 以防万一它被埋在这里。 它来自AMD组装程序员。他说C程序员(人)没有意识到他们的代码效率低下。他今天说,但是,gcc编译器非常好,使像他这样的人破产了。他举例称,并告诉我关于while 1VS for(;;)。我现在已经习惯使用它了,但是由于它们已经过优化,因此gcc尤其是解释器这两天都将执行相同的操作(处理器跳转)。

7
标准委员会关注的异国架构
我知道C和C ++标准留下了语言实现定义的许多方面,只是因为如果存在具有其他特征的体系结构,那么将很难或不可能为其编写符合标准的编译器。 我知道40年前,任何计算机都有其自己的独特规范。但是,我不知道今天使用的任何架构在哪里: CHAR_BIT != 8 signed 不是两个的补码(我听说Java对此有问题)。 浮点不符合IEEE 754(编辑:我的意思是“不是采用IEEE 754二进制编码”)。 我问的原因是,我经常向人们解释,C ++不要求其他任何低级方面(例如固定大小的类型†)是很好的。很好,因为与“其他语言”不同,它可以使您的代码在正确使用时可移植(编辑:因为可以将其移植到更多体系结构中,而无需模拟机器的低级方面,例如,符号+幅值体系中的二进制补码算法) 。但是我很难为自己不能指出任何特定的体系结构。 所以问题是:哪些架构具有上述特性? † uint*_t是可选的。
154 c++  c  architecture 

11
C ++弃用了从字符串常量到'char *'的转换
我有一堂课 private char str[256]; 为此,我有一个显式的构造函数: explicit myClass(const char *func) { strcpy(str,func); } 我称其为: myClass obj("example"); 当我对此进行编译时,会收到以下警告: 从字符串常量到'char *'的弃用转换 为什么会这样呢?



4
是“ long long” =“ long long int” =“ long int long” =“ int long long”吗?
我找到了两者,long int long并且int long long可以编译为变量类型。是否有任何区别long int long,int long long,long long和long long int? 通常,如果类型的数目相同,类型是否相同long? 1长: long l; int long il; long int li; 2长: long long ll; int long long ill; long int long lil; long long int lli; 同样,如果以上正确,以下声明是否也相同? long long* llp; int long long* illp; long int long* lilp; …
153 c++  syntax  long-integer 

4
是否正确定义了“ false <true”操作?
C ++规范是否定义: 布尔参数是否存在“小于”运算符,如果存在, 4个参数排列的结果? 换句话说,规范定义了以下操作的结果吗? false &lt; false false &lt; true true &lt; false true &lt; true 在我的设置(Centos 7,gcc 4.8.2)上,下面的代码显示了我期望的结果(给定C将false表示为0,将true表示为1的历史): false &lt; false = false false &lt; true = true true &lt; false = false true &lt; true = false 虽然我可以肯定大多数(所有?)编译器都将提供相同的输出,但是C ++规范是否对此做了规定?还是允许混淆但符合规范的编译器确定true小于false? #include &lt;iostream&gt; const char * s(bool a) { …

8
优化了“ while(1);” 在C ++ 0x中
更新,请参见下文! 我听说过,C ++ 0x允许编译器为以下代码段打印“ Hello” #include &lt;iostream&gt; int main() { while(1) ; std::cout &lt;&lt; "Hello" &lt;&lt; std::endl; } 显然,它与线程和优化功能有关。在我看来,这会让很多人感到惊讶。 有人对为什么要允许这样做有很好的解释吗?作为参考,最新的C ++ 0x草案在6.5/5 在for语句的情况下,在for-init-statement之外的循环, 不调用库I / O函数,并且 不访问或修改易失性对象,并且 不执行任何同步操作(1.10)或原子操作(第29条) 实现可能会假定它终止。[注意:这旨在允许编译器进行转换,例如删除空循环,即使无法证明终止也是如此。—尾注] 编辑: 这篇有见地的文章谈到了该标准文本 不幸的是,没有使用“未定义行为”一词。但是,只要该标准说“编译器可以假定P”,就意味着具有not-P属性的程序具有未定义的语义。 这是正确的,并且允许编译器为上述程序打印“ Bye”吗? 这里有一个更具洞察力的线程,它与对C的类似更改有关,由Guy在上面的链接文章中开始。在其他有用的事实中,他们提出了一种似乎也适用于C ++ 0x的解决方案(更新:在n3225上将不再起作用-参见下文!) endless: goto endless; 看来,不允许编译器对其进行优化,因为这不是循环,而是跳转。另一个人总结了C ++ 0x和C201X的拟议更改 通过编写一个循环,程序员断言或者环路不可见的东西的行为(执行I / O,访问volatile对象,或进行同步或原子操作), 或者,它最终会终止。如果我通过写一个没有副作用的无限循环违反了这一假设,那我就是对编译器撒谎,而我的程序的行为是不确定的。(如果幸运的话,编译器可能会警告我。)该语言不提供(不再提供?)一种表达无可见行为的无限循环的方法。 在2011年3月31日更新了n3225:委员会将文本移至1.10 / 24并说 …

6
为什么不能用LR(1)解析器解析C ++?
我正在阅读有关解析器和解析器生成器的信息,并在Wikipedia的LR解析页面中找到以下语句: 可以使用LR解析器的某些变体来解析许多编程语言。C ++是一个值得注意的例外。 为什么会这样呢?C ++的哪些特殊属性导致无法使用LR解析器进行解析? 使用谷歌,我只发现C可以用LR(1)完美解析,但是C ++需要LR(∞)。

7
用c ++ 11等效项替换boost :: thread和boost :: mutex是否明智?
动机:我正在考虑的原因是,我的天才项目经理认为boost是另一种依赖,并且它很可怕,因为“您依赖它”(我试图解释boost的质量,然后过了一段时间就放弃了:( )。我之所以愿意这样做的较小原因是我想学习c ++ 11的功能,因为人们将开始在其中编写代码。 #include&lt;thread&gt; #include&lt;mutex&gt;和Boost等价物之间是否存在1:1映射? 您是否认为用c ++ 11的 东西代替boost的东西是个好主意?我的用法是原始的,但是有没有一些示例说明std不提供什么功能呢?或(亵渎)反之亦然? PS我使用GCC,所以标题在那里。


14
在C / C ++中检查NULL指针[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引文回答。 5年前关闭。 改善这个问题 在最近的代码审查中,贡献者试图强制NULL以下列方式执行对指针的所有检查: int * some_ptr; // ... if (some_ptr == NULL) { // Handle null-pointer error } else { // Proceed } 代替 int * some_ptr; // ... if (some_ptr) { // Proceed } else { // Handle null-pointer error } 我同意他的方法在某种意义上更为清晰,因为它明确地说“确保此指针不为NULL”,但我要反驳这一点,说的是从事此代码工作的任何人都将理解在指针中使用指针变量。if语句隐式检查NULL。我也觉得第二种方法引入类似漏洞的可能性较小: if (some_ptr = NULL) 这只是查找和调试的绝对痛苦。 …

13
num ++是否可以对“ int num”是原子的?
通常,for int num,num++(或++num)作为读取-修改-写入操作不是原子的。但是我经常看到编译器(例如GCC)为此生成以下代码(请尝试在此处): 由于对应的第5行num++是一条指令,在这种情况下,我们可以得出结论num++ 是原子的吗? 如果是这样,是否意味着这样生成的代码num++可以在并发(多线程)场景中使用,而不会造成数据争用的危险(即,例如,我们不需要这样做,std::atomic&lt;int&gt;并且会产生相关的成本,因为它反正还是原子的? 更新 注意,这个问题不是增量是否是原子的(不是,那过去是,现在是问题的开头)。这是在特定情况下是否可以使用,即在某些情况下是否可以利用单指令性质来避免lock前缀的开销。并且,正如公认的答案在有关单处理器机器的部分中提到的那样,以及该答案,其注释中的对话和其他解释都可以(尽管不是使用C或C ++)。

6
当main()退出时,一个分离的线程会怎样?
假设我先启动一个std::thread,然后启动detach()它,那么即使std::thread那个曾经代表它,但超出范围,线程仍继续执行。 进一步假定该程序不具有用于加入分离线程1的可靠协议,因此分离线程在main()退出时仍然运行。 我无法在标准(更确切地说,在N3797 C ++ 14草案中)中找到任何内容,该标准描述了应该发生的情况,无论1.10还是30.3都没有相关的措辞。 1另一个可能等效的问题是:“是否可以再次连接一个分离的线程”,因为无论您想加入哪种协议,都必须在线程仍在运行时完成信令部分,并且OS调度程序可能决定在执行信令后立即使线程休眠一个小时,而接收端无法可靠地检测到线程实际上已完成。 如果main()用分离的线程运行时耗尽是未定义的行为,则除非主线程永不退出2,否则对的任何使用std::thread::detach()都是未定义的行为。 因此,main()用分离的线程运行时用尽必须具有定义的效果。问题是:在哪里定义了这些效果(在C ++标准中,不是POSIX,不是OS docs,...)。 2分离的线程无法连接(在的意义上std::thread::join())。您可以等待来自分离线程的结果(例如,通过来自的Future std::packaged_task或通过计数信号量或标志和条件变量),但这不能保证线程已完成执行。事实上,除非你把信令部分进入线程的第一个自动对象的析构函数,也将在一般情况下,是代码(析构函数),其运行后的信号代码。如果操作系统安排主线程使用结果并在分离的线程完成运行所述析构函数之前退出,那么将定义发生什么?

11
RTTI的价格是多少?
我了解使用RTTI会带来资源损失,但是它有多大?我看过的每个地方都只是说“ RTTI很昂贵”,但是它们都没有给出任何基准或定量的数据保护内存,处理器时间或速度。 那么,RTTI到底有多贵?我可能会在只有4MB RAM的嵌入式系统上使用它,因此每一位都很重要。 编辑:根据S. Lott的回答,如果我包括我实际在做的事情会更好。 我正在使用一个类来传递不同长度的数据,并且可以执行不同的操作,因此仅使用虚函数很难做到这一点。似乎使用了一些dynamic_cast s可以通过允许不同的派生类通过不同的级别传递而仍然允许它们采取完全不同的操作来解决此问题。 据我了解,dynamic_cast它使用RTTI,所以我想知道在有限的系统上使用RTTI的可行性。
152 c++  performance  rtti 

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.