标签: c++17

为什么即使我使用[[fallthrough]],GCC也会警告我一个漏洞?

在下面的代码中,我使用[[fallthrough]]C++ 1z中的标准属性来记录需要的漏洞:

#include <iostream>

int main() {
    switch (0) {
        case 0:
            std::cout << "a\n";
            [[fallthrough]]
        case 1:
            std::cout << "b\n";
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用GCC 7.1,代码编译时没有错误.但是,编译器仍然警告我一个问题:

warning: this statement may fall through [-Wimplicit-fallthrough=]
    std::cout << "a\n";
    ~~~~~~~~~~^~~~~~~~
Run Code Online (Sandbox Code Playgroud)

为什么?

c++ switch-statement fall-through c++17

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

自C++ 17以来,具有正确地址和类型的指针仍然始终是有效指针吗?

(参考这个问题和答案.)

在C++ 17标准之前,[basic.compound]/3中包含以下句子:

如果类型T的对象位于地址A,则类型为cv T*的指针(其值为地址A)被称为指向该对象,而不管该值是如何获得的.

但是自从C++ 17以来,这句话已被删除.

例如,我相信这句话使这个示例代码定义,并且从C++ 17开始这是未定义的行为:

 alignas(int) unsigned char buffer[2*sizeof(int)];
 auto p1=new(buffer) int{};
 auto p2=new(p1+1) int{};
 *(p1+1)=10;
Run Code Online (Sandbox Code Playgroud)

在C++ 17之前,p1+1保持地址*p2并具有正确的类型,因此*(p1+1)是指向*p2.在C++中,17 p1+1是一个指向前端指针,所以它不是指向对象指针,我相信它不是可以解除引用的.

对标准权的这种修改的解释是否还有其他规则来补偿所引用的句子的删除?

c++ pointers language-lawyer c++14 c++17

80
推荐指数
2
解决办法
4177
查看次数

什么是模板扣除指南以及何时使用它们?

C++ 17标准引入了"模板推导指南".我认为它们与此版本标准中引入的构造函数的新模板参数推导有关,但我还没有看到一个简单的,常见问题解答风格的解释,它们是什么以及它们的用途.

  • 什么是C++ 17中的模板推导指南?

  • 为什么(以及何时)我们需要它们?

  • 我该如何申报?

c++ templates c++-faq template-argument-deduction c++17

78
推荐指数
1
解决办法
8725
查看次数

Initializing variables in an "if" statement

I read that in C++17 we can initialize variables in if statements like this

if (int length = 2; length == 2)
    //execute something
Run Code Online (Sandbox Code Playgroud)

Instead of

int length = 2;
if (length == 2)
    //do something
Run Code Online (Sandbox Code Playgroud)

Even though it is shorter, it affects the code readability (especially for people who don't know this new feature), which I suppose is a bad coding practice for large software development.

除了使代码更短之外,使用此功能还有什么好处?

c++ c++17

78
推荐指数
6
解决办法
4834
查看次数

C++ 17引入了哪些评估顺序保证?

在典型的C++代码中,C++ 17评估顺序保证(P0145)投票的含义是什么?

对于像这样的事情,它有什么变化

i=1;
f(i++, i)
Run Code Online (Sandbox Code Playgroud)

std::cout << f() << f() << f() ;
Run Code Online (Sandbox Code Playgroud)

要么

f(g(),h(),j());
Run Code Online (Sandbox Code Playgroud)

c++ operator-precedence c++17

77
推荐指数
2
解决办法
7130
查看次数

保证副本省略如何运作?

在2016年奥卢ISO C++标准会议上,标准委员会将一项名为" 保证副本省略"的提案通过简化的价值类别投票进入C++ 17.

保证副本省略如何运作?是否涵盖了某些已经允许复制省略的情况,或者是否需要更改代码来保证复制省略?

c++ copy-elision c++17

75
推荐指数
1
解决办法
7883
查看次数

是否允许编译器优化本地volatile变量?

是否允许编译器对此进行优化(根据C++ 17标准):

int fn() {
    volatile int x = 0;
    return x;
}
Run Code Online (Sandbox Code Playgroud)

这个?

int fn() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果是,为什么?如果没有,为什么不呢?


这里有一些关于这个主题的思考:当前编译器编译fn()为放在堆栈上的局部变量,然后返回它.例如,在x86-64上,gcc创建了这个:

mov    DWORD PTR [rsp-0x4],0x0 // this is x
mov    eax,DWORD PTR [rsp-0x4] // eax is the return register
ret    
Run Code Online (Sandbox Code Playgroud)

现在,据我所知,标准并没有说应该将一个局部volatile变量放在堆栈上.所以,这个版本同样好:

mov    edx,0x0 // this is x
mov    eax,edx // eax is the return
ret    
Run Code Online (Sandbox Code Playgroud)

这里,edx商店x.但是现在,为什么要停在这里?由于edxeax均为零,我们可以只说:

xor    eax,eax // eax is the return, and x as well
ret    
Run Code Online (Sandbox Code Playgroud)

我们转变 …

c++ volatile language-lawyer c++17

75
推荐指数
5
解决办法
5748
查看次数

experimental :: filesystem链接器错误

我尝试在gcc 6.0中使用新的c ++ 1z功能实际开发.

如果我尝试这个小例子:

#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
int main()
{
    fs::path p1 = "/home/pete/checkit";

    std::cout << "p1 = " << p1 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我有:

/opt/linux-gnu_6-20151011/bin/g++ --std=c++1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: In function \`std::experimental::filesystem::v1::__cxx11::path::path(char const (&) [36])':
/opt/linux-gnu_6-20151011/include/c++/6.0.0/experimental/bits/fs_path.h:167: undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status

gcc版本是快照linux-gnu_6-20151011

任何提示如何链接新的c ++ 1z功能?

c++ gcc c++17

72
推荐指数
4
解决办法
4万
查看次数

std::string s1 {"现代 C++", 3} 与 std::string s1 {str, 3}

以下代码的输出让我感到困惑:

const std::string str = "Modern C++";

std::string s1 {"Modern C++", 3};
std::string s2 {str, 3};

std::cout << "S1: " << s1 << "\n";
std::cout << "S2: " << s2 << "\n";
Run Code Online (Sandbox Code Playgroud)

输出:

> S1: Mod
> S2: ern C++
Run Code Online (Sandbox Code Playgroud)

谁能解释这个结果?

c++ string c++17

69
推荐指数
3
解决办法
2446
查看次数

在C++函数中"返回"的确切时刻

这似乎是一个愚蠢的问题,但是return xxx;在一个明确定义的函数中"执行" 的确切时刻?

请参阅以下示例以了解我的意思(现在直播):

#include <iostream>
#include <string>
#include <utility>

//changes the value of the underlying buffer
//when destructed
class Writer{
public:
    std::string &s;
    Writer(std::string &s_):s(s_){}
    ~Writer(){
        s+="B";
    }
};

std::string make_string_ok(){
    std::string res("A");
    Writer w(res);
    return res;
}


int main() {
    std::cout<<make_string_ok()<<std::endl;
} 
Run Code Online (Sandbox Code Playgroud)

我天真地期待发生的事情make_string_ok被称为:

  1. 构造函数res被调用(价值res就是"A")
  2. w调用构造函数
  3. return res被执行.应该返回res的当前值(通过复制当前值res),即"A".
  4. w被称为析构函数,值res变为"AB".
  5. 析构res函数被称为.

所以我希望"A"结果,但"AB" …

c++ object-lifetime language-lawyer copy-elision c++17

67
推荐指数
3
解决办法
4121
查看次数