小编Sha*_*our的帖子

C++ 11成员初始化列表与类内初始化程序?

在C++ 11中初始化对象成员变量的这些方法有何不同?还有另外一种方法吗?哪种方式更好(性能)?:

class any {
  public:
    obj s = obj("value");
    any(){}
};
Run Code Online (Sandbox Code Playgroud)

要么

class any {
  public:
    obj s;
    any(): s("value"){}
};
Run Code Online (Sandbox Code Playgroud)

谢谢.

c++ initialization c++11

38
推荐指数
3
解决办法
1万
查看次数

为什么用!!(条件)代替(条件)?

我见过人们使用带有两个'!'的条件子句的代码

#define check_bit(var, pos)       (!!((var) & (1 << (pos))))
#define likely(x)       __builtin_expect(!!(x),1)
#define unlikely(x)     __builtin_expect(!!(x),0)
Run Code Online (Sandbox Code Playgroud)

是我能找到的一些例子.

使用!!(condition)结束有什么好处(condition)吗?

c logical-operators

35
推荐指数
2
解决办法
2285
查看次数

功能优化为'gcc -O2'的无限循环

背景
我被一位朋友问过以下谜题:

void fn(void)
{
  /* write something after this comment so that the program output is 10 */
  /* write something before this comment */
}

int main()
{
  int i = 5;
  fn();
  printf("%d\n", i);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我知道可以有多个解决方案,一些涉及宏,一些假设有关实现和违反C.

我感兴趣的一个特定解决方案是对堆栈做出某些假设并编写以下代码:(我知道它是未定义的行为,但可能在许多实现中按预期工作)

void fn(void)
{
  /* write something after this comment so that the program output is 10 */
  int a[1] = {0};
  int j = 0;
  while(a[j] != 5) ++j;  /* Search stack until you find 5 */
  a[j] …
Run Code Online (Sandbox Code Playgroud)

c optimization gcc undefined-behavior

34
推荐指数
3
解决办法
3203
查看次数

给定int**p1和const int**p2是p1 == p2是否形成良好?

鉴于以下功能:

void g(int **p1, const int**p2)
{
   if (p1 == p2) { }  
}
Run Code Online (Sandbox Code Playgroud)

clang(返回3.0版)产生此警告(请参见实时):

warning: comparison of distinct pointer types ('int **' and 'const int **')
uses non-standard composite pointer type 'const int *const *' 
[-Wcompare-distinct-pointer-types]
  if (p1 == p2) { }
      ~~ ^ ~~
Run Code Online (Sandbox Code Playgroud)

使用-pedantic-errors标志会将其变为错误.根据标准,两者gcc(回到4.3.6)和Visual Studio(2013)都没有产生警告,是比较:

p1 == p2
Run Code Online (Sandbox Code Playgroud)

结构良好?

更一般地说,如果两个多级指针的cv资格不同于第一级,那么通过等式运算符或关系运算符进行比较是否良好?

c++ language-lawyer c++11 c++14

34
推荐指数
1
解决办法
1392
查看次数

具有非静态成员初始值设定项的类的C++ 11聚合初始化

是否允许标准:

struct A
{
  int a = 3;
  int b = 3;
};

A a{0,1}; // ???
Run Code Online (Sandbox Code Playgroud)

这个课程仍然是聚合的吗? clang接受此代码,但gcc不接受.

c++ gcc aggregate-initialization c++11 c++14

33
推荐指数
1
解决办法
6519
查看次数

std :: map参数,带有空的brace-initializers,用于GCC中的默认参数segfaults

问题

我收到了用户报告我开发的库中的段错误的错误报告.

错误代码的最小示例是:

#include <map>
#include <string>
#include <iostream>

void f(std::map<std::string, std::string> m = {})
{
        std::cout << m.size() << "\n";
        for (const auto& s: m) {
                std::cout << s.first << "->" << s.second <<"\n";
        }
}

int main()
{
        f();
}
Run Code Online (Sandbox Code Playgroud)

当使用GCC编译时(我测试了4.8.2和4.7.3),它正确地打印0为容器的大小,但是循环内部的段错误(根本不应该执行).

解决方法

不过,我可以修复通过改变声明的问题:

void f(std::map<std::string, std::string> m = std::map<std::string, std::string>{})
Run Code Online (Sandbox Code Playgroud)

复制map作品:

void f(std::map<std::string, std::string> mx = {})
{
        auto m = mx;
        std::cout << m.size() << "\n";
        for (const auto& s: m) …
Run Code Online (Sandbox Code Playgroud)

c++ gcc default-arguments c++11

33
推荐指数
1
解决办法
945
查看次数

如果计数大于类型的宽度,是右移未定义的行为吗?

我刚检查了C++标准.看来以下代码不应该是未定义的行为:

unsigned int val = 0x0FFFFFFF;
unsigned int res = val >> 34;  // res should be 0 by C++ standard,
                               // but GCC gives warning and res is 67108863
Run Code Online (Sandbox Code Playgroud)

并从标准:

E1 >> E2的值是E1右移E2位位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1/2 ^ E2的商的整数部分.如果E1具有有符号类型和负值,则生成的值是实现定义的.

根据标准,由于34不是负数,因此变量res将为0.

GCC为代码段提供以下警告,并且res67108863:

警告:右移计数> =类型的宽度

我还检查了GCC发出的汇编代码.它只是调用SHRL,而SHRL的英特尔指令文件res不是ZERO.

那么这是否意味着GCC没有在英特尔平台上实现标准行为?

c++ assembly standards gcc undefined-behavior

32
推荐指数
2
解决办法
6393
查看次数

带名称空间的编译器的有趣行为

假设以下代码:

#include <iostream>
using namespace std;

namespace X
{
  class A{};

  void f(A a){}

  void g(int a){}
}

int main()
{
  X::A a;
  f(a);
  g(5);
}
Run Code Online (Sandbox Code Playgroud)

编译代码时,会发生以下编译错误:

main.cpp:在函数'int main()'中:
main.cpp:error:'g'未在此范围内声明

所以函数f编译得很完美,但事实g并非如此.怎么样?它们都属于同一名称空间.编译器是否从类型的参数中推断出该函数f属于X命名空间X::A?在这种情况下编译器如何表现?

c++ namespaces compiler-errors argument-dependent-lookup

32
推荐指数
3
解决办法
1169
查看次数

为什么不能在do while循环的表达式部分中声明变量?

以下语法有效:

while (int i = get_data())
{
}
Run Code Online (Sandbox Code Playgroud)

但以下不是:

do
{
} while (int i = get_data());
Run Code Online (Sandbox Code Playgroud)

我们可以通过标准草案N41406.4节了解原因:

1 [...]

condition:
     expression
     attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
     attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list

2条件规则既适用于选择陈述,也适用于forwhile陈述(6.5).[...]

和第6.5

1迭代语句指定循环.

      iteration-statement: 
             while ( condition ) statement
             do statement while ( expression ) ;

相反,你被迫做一些丑陋的事情:

int i = get_data();
do
{
} while ((i = get_data())); // double parentheses sic
Run Code Online (Sandbox Code Playgroud)

这是什么理由?

c++ declaration do-while

32
推荐指数
4
解决办法
5260
查看次数

将字符串作为指针或文字传递时,strcmp()返回值不一致

strcmp当我注意到这一点时,我正在玩,这里是代码:

#include <string.h>
#include <stdio.h>

int main(){

    //passing strings directly
    printf("%d\n", strcmp("ahmad", "fatema"));

    //passing strings as pointers 
    char *a= "ahmad";
    char *b= "fatema";
    printf("%d\n",strcmp(a,b));

    return 0;

}
Run Code Online (Sandbox Code Playgroud)

输出是:

-1
-5
Run Code Online (Sandbox Code Playgroud)

不应该strcmp一样吗?为什么,我给我传递一个字符串作为不同的值"ahmad"或作为char* a = "ahmad".将值传递给函数时,它们是否在其堆栈中分配?

c c++ linux strcmp

32
推荐指数
2
解决办法
1852
查看次数