标签: gcc8

保证复制省略的行为是否依赖于用户定义的复制构造函数的存在?

以下代码在GCC 8.0.1下使用或不使用用户定义的复制构造函数的行为有所不同:

#include <cassert>

struct S {
    int i;
    int *p;
    S() : i(0), p(&i) {}
    // S(const S &s) : i(s.i), p(&i) {}  // #1
    // S(const S &s) : i(s.i), p(s.p) {} // #2
    // S(const S &s) = delete;           // #3
};

S make_S() {return S{};}

int main()
{
    S s = make_S();
    assert(s.p == &s.i);
}
Run Code Online (Sandbox Code Playgroud)

使用注释的用户定义的复制构造函数(即使是#2,执行简单的浅复制的那个),断言也不会失败,这意味着保证的复制省略按预期工作.

然而,在没有任何用户定义的复制构造,则断言失败,这意味着该对象smain功能不被缺省构造.为什么会这样?保证复制省略不在这里执行吗?

c++ language-lawyer copy-elision c++17 gcc8

16
推荐指数
1
解决办法
631
查看次数

gcc-8 -Wstringop-truncation有什么好的做法?

海湾合作委员会8增加了-Wstringop-truncation警告.来自https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82944:

在GCC 8.0中通过r254630为bug 81117添加的-Wstringop-truncation警告专门用于突出显示strncpy函数的非预期用途,该函数截断源字符串中的终止NUL字符.请求中给出的此类滥用的示例如下:

char buf[2];

void test (const char* str)
{
  strncpy (buf, str, strlen (str));
}
Run Code Online (Sandbox Code Playgroud)

我用这段代码得到了同样的警告.

strncpy(this->name, name, 32);

warning: 'char* strncpy(char*, const char*, size_t)' specified bound 32 equals destination size [-Wstringop-truncation`]
Run Code Online (Sandbox Code Playgroud)

考虑到this->namechar name[32]name是一个char*具有长度可能比32更大我想复制namethis->name和截断它,如果它是大于32更大的应该size_t是31而不是32?我糊涂了.this->nameNUL终止并不是强制性的.

c++ gcc strncpy gcc8

7
推荐指数
3
解决办法
5572
查看次数

Google Sparsehash在类型上使用realloc(),这不是简单的可复制

考虑这个简单的程序:

#include <string>
#include <sparsehash/dense_hash_map>

int main()
{
    google::dense_hash_map<std::string, int> map;
    map["foo"] = 0;
}
Run Code Online (Sandbox Code Playgroud)

使用GCC 8.2和-Wclass-memaccess(或-Wall)进行编译会产生警告:

sparsehash/internal/libc_allocator_with_realloc.h:68:40: warning:
‘void* realloc(void*, size_t)’ moving an object of non-trivially copyable type
    ‘struct std::pair<const std::__cxx11::basic_string<char>, int>’;
use ‘new’ and ‘delete’ instead [-Wclass-memaccess]
    return static_cast<pointer>(realloc(p, n * sizeof(value_type)));
                                ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

问题是:

  1. 是不确定的行为?
  2. 您能否建议可以应用于应用程序代码的修复或解决方法(不是通过更改Sparsehash或避免使用它)?
  3. (加分点)你能构造一个实际上由于这个而行为不正常的程序(使用std :: string或你自己的非平凡类型)?到目前为止,我还没有看到使用std :: string作为密钥类型的代码中的任何问题,尽管std :: string必须是一个非常常用的密钥类型.

我在这里提出了一个问题:https://github.com/sparsehash/sparsehash/issues/149

c++ realloc undefined-behavior sparsehash gcc8

6
推荐指数
1
解决办法
281
查看次数

vector 必须与它的分配器具有相同的值

此 MCVE 使用 gcc 7.3 编译/运行:
请注意,此 MCVE 已显着减少以保持错误重现,因此Allocator模板中的代码没有意义,但不会影响星座!

#include <regex>
#include <string>
#include <iostream>

namespace FaF
{
    template <typename T>
    class Allocator
    {
        public:
            typedef T value_type;

            Allocator() throw() {}
            template <typename U> Allocator (const Allocator<U>&) throw() {}
            ~Allocator() throw() {}

            T* allocate (std::size_t num, const void* hint = 0)
            {
                (void) hint; (void) num;
                return  new ( T );
            }

            void deallocate (T* p, std::size_t num) { (void) num; (void) p; }
    };

    using string = …
Run Code Online (Sandbox Code Playgroud)

c++ c++17 gcc8

5
推荐指数
1
解决办法
989
查看次数

在Windows 10上使用nuwen MinGW的C ++ 17文件系统

我想尝试在C ++ 17的新的文件系统库,因此试图复制从cppreference.com的std ::文件系统::例子的current_path并使用最新版本(16.0)编译它MinGW的分布从nuwen.net上我的Windows 10 x64计算机。其中包括gcc v8.1,根据cppreference.com编译器支持页面,该文件应支持文件系统库。

这是我要编译的代码:

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
    std::cout << "Current path is " << fs::current_path() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

和我正在使用的编译器命令:

g++ -std=c++17 filesystem_test.cpp
Run Code Online (Sandbox Code Playgroud)

这是我尝试编译时遇到的错误:

In file included from c:\mingw\include\c++\8.1.0\filesystem:37,
                 from filesystem_test.cpp:2:
c:\mingw\include\c++\8.1.0\bits\fs_path.h: In member function 'std::filesystem::__cxx11::path& std::filesystem::__cxx11::path::operator/=(const std::filesystem::__cxx11::path&)':
c:\mingw\include\c++\8.1.0\bits\fs_path.h:237:47: error: no match for 'operator!=' (operand types are 'std::filesystem::__cxx11::path' and 'std::filesystem::__cxx11::path')
    || (__p.has_root_name() && __p.root_name() != root_name()))
                               ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
In file included from c:\mingw\include\c++\8.1.0\iosfwd:40,
                 from …
Run Code Online (Sandbox Code Playgroud)

c++ mingw-w64 windows-10 c++17 gcc8

5
推荐指数
1
解决办法
2569
查看次数

使用 gcc 8.2.1 时的 strncat Wformat-overflow 警告

我正在使用 gcc 8.2.1 并尝试构建此代码:

std::string dir = "Documents";
char * _tempname = static_cast <char*> (malloc( dir.length() + 14));
strncpy (_tempname, dir.c_str(), dir.length()+1 );
strncat (_tempname, "/hellooXXXXXX", 13);
Run Code Online (Sandbox Code Playgroud)

但它给了我这个警告:

警告:'char* strncat(char*, const char*, size_t)'指定的边界 13 等于源长度 [-Wstringop-overflow=]

搜索后,我发现根据此链接中的讨论,size_t 等于源长度是一个溢出问题,但我不明白为什么这被认为是一个问题以及为什么这会溢出目标。以及如何在不更改代码的情况下删除此警告?

c++ string gcc gcc-warning gcc8

4
推荐指数
1
解决办法
6292
查看次数

构建 gcc 8.3 [Makefile:955: all] 错误 2

我一直在尝试在新的 Ubuntu 20.04 机器上构建特定版本的 GCC (8.3.0)。但是,当我按照以下链接中的步骤操作时:https://gcc.gnu.org/wiki/InstallingGCC我遇到了 Makefile 错误。

脚步:

wget https://ftp.gnu.org/gnu/gcc/gcc-8.3.0/gcc-8.3.0.tar.xz
tar xf gcc-8.3.0.tar.xz
cd gcc-8.3.0
./contrib/download_prerequisites
cd .. ; mkdir build ; cd build
../gcc-8.3.0/configure --prefix=/opt/gcc-8.3 --enable-languages=c,c++,fortran --disable-multilib
Run Code Online (Sandbox Code Playgroud)

配置输出:

checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether ln works... yes
checking whether ln -s works... yes
checking for a sed that does not truncate output... /usr/bin/sed
checking for gawk... no
checking …
Run Code Online (Sandbox Code Playgroud)

gcc makefile build gcc8

4
推荐指数
1
解决办法
3175
查看次数

gcc-8 Wstringop 截断

我正在尝试修复一些 gcc-8 抱怨 Wstringop-truncation 的 C 代码(代码在这里

\n\n

当在我无法控制的服务器上编译该代码时,既不能添加编译指示语句,也不能禁用 Wstringop-truncation 诊断,我收到的警告是:

\n\n
gcc-8  -I"/home/hornik/tmp/R/include" -DNDEBUG -I./cqdb/include -I./crf/src -I./liblbfgs/include -I./include -I"/home/hornik/lib/R/Library/3.6/x86_64-linux-gnu/Rcpp/include" -I/usr/local/include   -fpic  -g -O2 -Wall -pedantic -mtune=native -c cqdb/src/cqdb.c -o cqdb/src/cqdb.o\ncqdb/src/cqdb.c: In function \xe2\x80\x98cqdb_writer_close\xe2\x80\x99:\ncqdb/src/cqdb.c:270:5: warning: \xe2\x80\x98strncpy\xe2\x80\x99 output truncated before terminating nul copying 4 bytes from a string of the same length [-Wstringop-truncation]\n     strncpy((char*)header.chunkid, CHUNKID, 4);\n     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ncqdb/src/cqdb.c: In function \xe2\x80\x98cqdb_reader\xe2\x80\x99:\ncqdb/src/cqdb.c:469:9: warning: \xe2\x80\x98strncpy\xe2\x80\x99 specified bound 4 equals destination size [-Wstringop-truncation]\n         strncpy((char*)db->header.chunkid, (const char*)p, 4);\n         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n\n

我想重写 strncpy 语句以删除这些警告。我是否正确,我需要替换以下几行

\n\n …

c gcc strncpy gcc8

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

使用std :: function类成员进行编译器优化时出现段错误

我有一个非常简单的代码示例,当-O2在gcc 8.2.0下进行优化时会崩溃

#include <vector>
#include <functional>
#include <iostream>

template<typename T, typename Container>
class Lambda_Expression
{
    using Lambda = std::function<T()>;
    const Lambda & _lambda;

public:
    Lambda_Expression(const Lambda & l) : _lambda(l) {}

    T operator[](const std::size_t i)
    {
        std::cerr << "inside expression [] " << i << std::endl;
        return _lambda();
    }
};

auto lambda = []() -> double
{
    return 1.0;
};

int main()
{
    int N = 10;
    std::vector<double> res(N, 0.0);

    double x = lambda();

    std::cerr << "before for …
Run Code Online (Sandbox Code Playgroud)

c++ lambda gcc c++17 gcc8

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

类内将不完整类型的 unique_ptr 初始化为 nullptr 时,gcc 编译错误

我正在使用 pimpl idiom 和 unique_ptr 编写一些代码。当我尝试使用类内初始化将 unique_ptr 默认设置为 nullptr 时,gcc 给出了编译错误,而 clang 和 msvc 都成功编译了代码。如果我没有使用类内初始化,错误就会消失。

\n\n
// A.h\n#pragma once\n\n#include <memory>\n\nusing namespace std;\n\nclass B;\nclass A\n{\nprivate:\n    ////////////////////////\n    // here gives the error!\n    ////////////////////////\n    unique_ptr<B> impl{nullptr}; // error only with gcc, \n                                 // ok with clang and msvc\n    unique_ptr<B> impl2; // ok with all three\n\npublic:\n    A();\n    ~A();\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n
// A.cpp\n#include "A.h"\n\nclass B\n{\nprivate:\n    int b{5};\n\npublic:\n    B() = default;\n    ~B() = default;\n};\n\nA::A() = default;\nA::~A() = default;\n
Run Code Online (Sandbox Code Playgroud)\n\n
// main.cpp\n#include "A.h"\n\nint main()\n{\n    A a;\n    return 0;\n}\n …
Run Code Online (Sandbox Code Playgroud)

c++ pimpl-idiom unique-ptr in-class-initialization gcc8

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