小编Ben*_*ler的帖子

结构的通用比较运算符

在许多单元测试中,我需要比较仅具有数据成员的简单结构的内容:

struct Object {
  int start;
  int stop;
  std::string message;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想写一些类似的东西:

CHECK(object1==object2);
Run Code Online (Sandbox Code Playgroud)

我总是必须实现:

bool operator==(const Object& lhs, const Object& rhs) {
   return lhs.start==rhs.start && lhs.stop==rhs.stop && lhs.message=rhs.message;
}
Run Code Online (Sandbox Code Playgroud)

Writing all these comparison functions becomes tedious, but is also prone to errors. Just imagine, what will happen if I add a new data member to Object, but the comparison operator will not be updated.

Then I remembered my knowledge in Haskell and the magic deriving(Eq) directive, which just generates a …

c++ stdtuple c++17

10
推荐指数
1
解决办法
132
查看次数

哪些函数受 -fno-math-errno 影响?

我对这篇文章感到兴奋:/sf/answers/4037224201/,我考虑使用-fno-math-errno. 但我想确保我不会损害我正在开发的软件的行为。

因此,我检查了(相当大的)代码库以查看errno正在使用的位置,并且我想确定这些用法是否会干扰-fno-math-errno. 但如何做到这一点呢?文档说:

-fno-数学错误号

在调用使用单条指令执行的数学函数(例如 sqrt...)后,请勿设置 errno

但我如何知道单条指令执行了哪些数学函数呢?这有记录在某处吗?在哪里?

似乎我使用的代码库errno特别依赖于调用strtol和使用流时。我猜这strtol不是用一条指令执行的。它是否被认为是一个数学函数?我怎样才能确定?

c++ gcc errno compiler-optimization math-functions

9
推荐指数
1
解决办法
901
查看次数

为什么没有std :: ios_base :: trunc的std :: ofstream截断?

根据此C ++参考:http : //www.cplusplus.com/reference/fstream/ofstream/ofstream/ ,的默认打开模式std::ofstreamios_base::out,并且没有提及其他隐式模式。因此,我希望如果用小文件覆盖大文件,则大文件的“超出”部分应保持不变,并且仅文件的第一部分应由较短的新数据代替。

另一方面,《 Apache C ++标准库用户指南》(http://stdcxx.apache.org/doc/stdlibug/30-3.html)在第30.3.1.2段的注释中指出:“对于输出文件流,打开模式输出等效于out | trunc,也就是说,您可以省略trunc标志。但是,对于双向文件流,必须始终明确指定trunc。

我已经试过这段代码:

#include <fstream>

int main()
{
    std::ofstream aFileStream("a.out", std::ios_base::out);
    aFileStream << "Hello world!";
    aFileStream.close();

    std::ofstream aFileStream2("a.out", std::ios::out);
    aFileStream2 << "Bye!";
    aFileStream2.close();
}
Run Code Online (Sandbox Code Playgroud)

无论是Windows上的g ++ 8.1和Linux上的g ++ 6.3,Apache文档似乎都是正确的。大文件被截断,在第二个文件流中写入较短的字符串后,没有任何内容。

为什么会这样呢?cplusplus.com错误吗?抑或行为令人沮丧?

c++ ofstream

8
推荐指数
1
解决办法
166
查看次数

链接时节垃圾回收对链接时优化有用吗?

众所周知,gcc / ld选项-ffunction-sections -fdata-sections -Wl,--gc-sections可以减小二进制大小(例如,请参见gcc的-ffunction-section和-fdata-sections选项的Query答案)。众所周知,链接时间优化可以减少二进制文件的大小和执行速度(例如,参见https://wiki.debian.org/LTO)。

但是,将节垃圾收集和链接时间优化结合起来会如何呢?链接时优化是否不应该使节垃圾收集多余?

我用mingw-w64 / g ++ 9.2.0用不同的编译器/链接器选项编译了Open CASCADE(https://www.opencascade.com/),并比较了二进制大小。打开CASCADE是一组多个dll。如果仅使用dll编译,则大多数dll最小-flto-flto -ffunction-sections -fdata-sections -Wl,--gc-sections相反,大多数情况下使用会稍微增加二进制文件的大小。但是,当添加垃圾回收选项时,有些dll实际上会变得略小。

为什么会这样?垃圾回收可能会删除哪些内容,而裸机链接时间优化无法删除哪些内容?是否有最佳实践,可以使用哪些编译/链接选项来减小二进制大小?

备注:我以为只会-flto更改执行时间(希望使二进制文件更快!),而链接时节垃圾回收很可能会将执行时间保持不变。我还没有时间来衡量。


编辑:为了使所描述的行为与现实的共享库可重现,我创建了一个bash脚本来构建带有两个不同参数集的Open CASCADE。第一行中的注释描述了如何修改脚本。我在Windows的MSYS2控制台中在这里使用它。

#!/bin/bash

# This script requires at least CMake 3.13, otherwise the options "-S" and "-B" do not work as expected.
# Further it needs a mingw-w64 installation in the path.

# Path to the folder that has been downloaded and extracted from https://www.opencascade.com/sites/default/files/private/occt/OCC_7.3.0_release/opencascade-7.3.0.tgz
OCCT_PATH="/c/Libraries/opencascade-7.3.0"

# …
Run Code Online (Sandbox Code Playgroud)

linker compiler-optimization gcc9

6
推荐指数
0
解决办法
100
查看次数

为什么对这个数组结构体的成员求和比对结构体数组求和要快得多?

我一直在使用https://github.com/google/benchmark和g++ 9.4.0来检查不同场景下数据访问的性能(用“ -O3”编译)。结果令我惊讶。

我的基线是访问std::array(“减少数据”)中的长数。我想添加一个额外的字节数据。一次我创建一个额外的容器(“拆分数据”),一次我在数组中存储一个结构(“组合数据”)。

这是代码:

#include <benchmark/benchmark.h>

#include <array>
#include <random>

constexpr int width  = 640;
constexpr int height = 480;

std::array<std::uint64_t, width * height> containerWithReducedData;

std::array<std::uint64_t, width * height> container1WithSplitData;
std::array<std::uint8_t, width * height>  container2WithSplitData;

struct CombinedData
{
    std::uint64_t first;
    std::uint8_t  second;
};

std::array<CombinedData, width * height> containerWithCombinedData;

void fillReducedData(const benchmark::State& state)
{
    // Variable is intentionally unused
    static_cast<void>(state);

    // Generate pseudo-random numbers (no seed, therefore always the same numbers)
    // NOLINTNEXTLINE
    auto engine …
Run Code Online (Sandbox Code Playgroud)

c++ arrays caching compiler-optimization data-oriented-design

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

使用 C++14 lambda 测量任意函数的执行时间

我对 Scott Meyer 的书“Effective Modern C++”的第 24 条感到很兴奋。他提到了编写 C++14 lambda 来记录任意函数调用所用时间的可能性。

我还处于学习 C++14 特性的早期阶段。我的尝试(Main.cpp)看起来像这样测量成员函数调用的时间:

#include <chrono>
#include <iostream>

auto measure = [](auto&& function, auto&&... parameters) -> decltype(function)
{
    const std::chrono::steady_clock::time_point startTimePoint =
    std::chrono::steady_clock::now();

    const auto returnValue = std::forward<decltype(function)>(function)(
            std::forward<decltype(parameters)>(parameters)...);

    const std::chrono::steady_clock::time_point stopTimePoint =
    std::chrono::steady_clock::now();

    const std::chrono::duration<double> timeSpan = std::chrono::duration_cast<
    std::chrono::duration<double>>(stopTimePoint - startTimePoint);

    std::cout << "Computation took " << timeSpan.count()
    << " seconds." << std::endl;

    return returnValue;
};

class Test
{
public:

    int computation(double dummy)
    {
        std::cout << "Received " << …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++-chrono c++14

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

为什么链接时间优化会导致分段错误?

我在使用参数构建的Windows上使用Mingw-w64 v7 和g++ 10.2 。我已经从这里下载并解压了bzip2 1.0.6:https : //sourceforge.net/projects/bzip2/。现在我在MSys2控制台中像这样构建boost 1.76.0 :--mode=gcc-10.2.0 --arch=x86_64 --buildroot=/c/mingw-builds/BuildRoot --update-sources --exceptions=seh --threads=posix --enable-languages=c++ --jobs=48 --rt-version=v7

./bootstrap.sh --with-libraries=iostreams --prefix=c:/Libraries/boost_1_76_0/InstallRelease
./b2 --layout=system variant=release link=shared address-model=64 threading=multi optimization=speed runtime-link=shared -s BZIP2_SOURCE=C:/Libraries/bzip2-1.0.6 install
Run Code Online (Sandbox Code Playgroud)

我想使用Boost.Iostreamsbzip2压缩一些流。因此,我创建了一个包含以下内容的测试文件 main.cpp:

#include <iostream>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>

int main() 
{
    {
        std::ofstream file("hello.z", std::ios_base::out | std::ios_base::binary);
        boost::iostreams::filtering_ostream out;
        out.push(boost::iostreams::bzip2_compressor());
        out.push(file);
        
        out << "Hello World!" << std::endl;
    }

    {
        std::ifstream file_in("hello.z", …
Run Code Online (Sandbox Code Playgroud)

c++ segmentation-fault boost-iostreams mingw-w64 link-time-optimization

5
推荐指数
0
解决办法
86
查看次数

如果一个类只有一个(模板化的)移动赋值运算符,为什么可以进行复制赋值?

今天无意中发现了一段代码,我不明白。请考虑以下示例:

#include <iostream>
#include <string>

class A
{
public:
    template <class Type>
    Type& operator=(Type&& theOther)
    {
        text = std::forward<Type>(theOther).text;

        return *this;
    }

private:
    std::string text;
};

class B
{
public:
    B& operator=(B&& theOther)
    {
        text = std::forward<B>(theOther).text;

        return *this;
    }

private:
    std::string text;
};

int main()
{
    A a1;
    A a2;
    a2 = a1;

    B b1;
    B b2;
    b2 = b1;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译时,MinGW-w64/g++ 10.2 指出:

..\src\Main.cpp: In function 'int main()':
..\src\Main.cpp:41:7: error: use of deleted function 'B& B::operator=(const …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 move-assignment-operator

5
推荐指数
2
解决办法
159
查看次数

为什么 g++ 10.1 会抱怨头文件中的命名 lambda 而其他人则不会?

我有一个带有命名 lambda 的头文件,用于测量某些函数的执行时间(该 lambda 部分是这个问题的结果How to Write a Lambda Wrapping a Function with Optional Return Value)。它驻留在我从几个翻译单元中包含的头文件中。这在 g++ 8 和 g++ 9 中运行良好。现在当我切换到 g++ 10.1 时,链接时出现错误。

请检查以下简化示例。

以下是 Wandbox 中的示例:https ://wandbox.org/permlink/Sizb6txrkW5dkJwT 。

文件“Lambda.h”:

#pragma once

#include <string>

auto measure = [](bool enabled, const std::string& taskName, auto&& function,
        auto&&... parameters) -> decltype(auto)
{
    return std::forward<decltype(function)>(function)(
            std::forward<decltype(parameters)>(parameters)...);
};
Run Code Online (Sandbox Code Playgroud)

文件“Test1.cpp”:

#include "Lambda.h"
Run Code Online (Sandbox Code Playgroud)

文件“Test2.cpp”:

#include "Lambda.h"
Run Code Online (Sandbox Code Playgroud)

然后我像这样构建:

g++ -c Test1.cpp
g++ -c Test2.cpp
g++ -shared -o Test.dll Test1.o Test2.o
Run Code Online (Sandbox Code Playgroud)

一切正常,直到 g++ 9.2,但使用 …

c++ g++ include generic-lambda c++14

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

如何在 Windows 上使用 GCC 11.1 构建 Qt 5.13.2?

我已经使用 GCC/MinGW-w64 在 Windows 上成功构建 Qt 5 很长时间了。当我在 GCC 11.1 上尝试同样的操作时,构建失败并出现奇怪的错误消息。我该怎么做才能让它发挥作用?

我自己使用https://github.com/niXman/mingw-buildsdevelop的分支和以下命令构建了编译器:

../build --mode=gcc-11.1.0 --arch=x86_64 --buildroot=/c/mingw-builds/BuildRoot --update-sources --exceptions=seh --threads=posix --enable-languages=c++ --jobs=48 --rt-version=v7
Run Code Online (Sandbox Code Playgroud)

然后我在 MSYS2 控制台上像这样检索 Qt:

# Ensure that the right Perl is being used to prevent the possible later compilation error "fatal error: QVector: No such file or directory"
export PATH=/c/Strawberry/perl/bin/:$PATH

cd /c
cd Libraries/
mkdir Qt
cd Qt
git clone git://code.qt.io/qt/qt5.git
cd qt5
git checkout v5.13.2
perl init-repository --module-subset=essential --berlin
cd ..
Run Code Online (Sandbox Code Playgroud)

然后我尝试构建 Qt:

mkdir Build …
Run Code Online (Sandbox Code Playgroud)

c++ qt gcc build qt5

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

如果实际对象不是const,则具有写操作的const_cast(this)是否具有未定义的行为?

我的问题是由我对另一个问题的回答所启发的:https : //stackoverflow.com/a/56989169/2492801

如果我有一个真正的非const对象,但调用它的一个const方法,那里面的方法thisconst当然的。如果我const_cast放弃其常量性并将其传递给对所指向的对象执行写操作的另一种方法,那this是未定义的行为吗?

如果确实如此,我不会感到惊讶,因为this它确实constconst方法内部。另一方面,对象本身不是对象,const因此通常不禁止写操作。

对我来说,重要的是要知道如何处理我的其他问题中所述的问题。谢谢!

c++ language-lawyer

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

为什么G ++不会对Const成员的未使用结果发出警告?

我对自己犯下的一个愚蠢的错误感到非常恼火.但我甚至更恼火的是我的编译器(g ++ 8.1)没有警告我.;-)

请考虑以下代码:

class Test
{
public:

    int getNumber() const
    {
        return 3;
    }
};

int main(void)
{
    Test test;
    test.getNumber();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我看来这条线

test.getNumber();
Run Code Online (Sandbox Code Playgroud)

绝对是错的.Test调用const成员,但不使用返回值.尽管我一直在用-Wall -Wextrag ++ 编译,但拒绝发出警告.我查过了文档-Wunused-result.如果我将该属性添加__attribute__ ((warn_unused_result))到该成员,那么编译器确实会警告我.

但为什么这有必要呢?是不是忽略了const方法的返回值总是错误的?我不应该warn_unused_result为所有const成员自动设置属性吗?

我对你的答案非常兴奋.

c++ g++ compiler-warnings

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

我可以从外部访问非类型模板类参数吗?如何?

请检查以下代码:

#include <iostream>

template <int Size>
class Test
{
  public:
    // Will not compile, if Size is not a type!
    // error: 'Size' does not name a type
    using MySize = Size;
    double array[Size];
};

using MyTestArray = Test<3>;

int main()
{
    MyTestArray testArray;

    std::cout << "Test array has size " << MyTestArray::MySize << std::endl;

    return 0;
}

Run Code Online (Sandbox Code Playgroud)

是否有可能Size在不引入这样的样板吸气剂的情况下从外部访问?

constexpr static int getSize() 
{
    return Size;
}
Run Code Online (Sandbox Code Playgroud)

c++ templates

0
推荐指数
1
解决办法
132
查看次数