标签: gcc9

如何使用 GCC 9 将 `std::filesystem::file_time_type` 转换为字符串

我正在尝试将文件的修改时间格式化为字符串 (UTC)。以下代码使用 GCC 8 编译,但不使用 GCC 9。

#include <chrono>
#include <filesystem>
#include <iomanip>
#include <iostream>
#include <sstream>

namespace fs = std::filesystem;

int main() {
    fs::file_time_type file_time = fs::last_write_time(__FILE__);
    std::time_t tt = decltype(file_time)::clock::to_time_t(file_time);
    std::tm *gmt = std::gmtime(&tt);
    std::stringstream buffer;
    buffer << std::put_time(gmt, "%A, %d %B %Y %H:%M");
    std::string formattedFileTime = buffer.str();
    std::cout << formattedFileTime << '\n';
}
Run Code Online (Sandbox Code Playgroud)

我使用 C++17 和 C++20 都尝试过decltype(file_time)::clockand std::chrono::file_clock,但它们都不起作用。

$ g++-9 -std=c++2a -Wall -Wextra -lstdc++fs file_time_type.cpp

file_time_type.cpp: In function ‘int main()’:
file_time_type.cpp:12:50: error: ‘to_time_t’ …
Run Code Online (Sandbox Code Playgroud)

c++ std-filesystem gcc9

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

使用 MINGW gcc 编译时,不会为 std::string 调用重载的 new 运算符

这个程序(用选项编译-std=c++17

#include <stdio.h>
#include <string>
void* operator new(std::size_t nrOfBytes) {
    printf("allocate %zd bytes on heap\n", nrOfBytes);
    void* p = malloc(nrOfBytes);
    if (p) {
        return p;
    } else {
       throw std::bad_alloc{};
    }
}
int main() {
    // new operator is called when compiled with Clang or MSVS or GCC 
    int* i = new int;
    delete i;
    // new operator is not called when compiled with GCC
    // but is called with Clang and MSVS 
    std::string str(2000, 'x');
    return 0; …
Run Code Online (Sandbox Code Playgroud)

c++ gcc stdstring gcc9

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

Canot从basic_stringstream &lt;char8_t&gt;读取char8_t

我只是stringstream在UTF-8中尝试:

#include<iostream>
#include<string>
#include<sstream>
int main()
{
    std::basic_stringstream<char8_t> ss(u8"hello");
    char8_t c;
    std::cout << (ss.rdstate() & std::ios_base::goodbit) << " " << (ss.rdstate() & std::ios_base::badbit) << " "
            << (ss.rdstate() & std::ios_base::failbit) << " " << (ss.rdstate() & std::ios_base::eofbit) << "\n";
    ss >> c;
    std::cout << (ss.rdstate() & std::ios_base::goodbit) << " " << (ss.rdstate() & std::ios_base::badbit) << " "
            << (ss.rdstate() & std::ios_base::failbit) << " " << (ss.rdstate() & std::ios_base::eofbit) << "\n";
    std::cout << c;
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

编译使用:

g++-9 …
Run Code Online (Sandbox Code Playgroud)

c++ gcc c++20 gcc9

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

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

众所周知,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
查看次数

警告:获取“结构详细信息”的打包成员的地址可能会导致未对齐的指针值 [-Waddress-of-packed-member]

       struct details_state {
               struct details_status D1;
               struct details_status D2;
       };

       struct details {
           struct details_state details_states[2];
       } __attribute__((packed));


        struct details *p;

        void print_details_status(struct details_status *s)

        print_details_status(&(p->details_states[i].D1));
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

警告:获取“结构详细信息”的打包成员的地址可能会导致未对齐的指针值 [-Waddress-of-packed-member]

GCC 在 >9 版本中给出此警告。如何在不使用 [-Wno-address-of-packed-member] 的情况下摆脱此警告

c struct gcc-warning gcc9 gcc11

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

uint32_t * uint32_t = uint64_t与gcc的向量乘法

我正在尝试将uint32_t产生完整64位结果的uint64_t向量乘以gcc 中的向量。我期望的结果是gcc发出一条VPMULUDQ指令。但是,gcc作为代码输出的结果是可怕地乱堆了各个uint32_t源向量,然后进行了完整的64 * 64 = 64乘法运算。这是我尝试过的:

#include <stdint.h>

typedef uint32_t v8lu __attribute__ ((vector_size (32)));
typedef uint64_t v4llu __attribute__ ((vector_size (32)));

v4llu mul(v8lu x, v8lu y) {
    x[1] = 0; x[3] = 0; x[5] = 0; x[7] = 0;
    y[1] = 0; y[3] = 0; y[5] = 0; y[7] = 0;
    return (v4llu)x * (v4llu)y;
}
Run Code Online (Sandbox Code Playgroud)

第一个掩盖了uint32_t向量的不需要部分,希望gcc可以优化掉64 * 64 = 64乘法的不需要部分,然后看到掩盖也是没有意义的。没有这种运气。

v4llu mul2(v8lu x, v8lu y) {
    v4llu tx = {x[0], …
Run Code Online (Sandbox Code Playgroud)

c gcc vectorization avx2 gcc9

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

为什么创建的线程数小于thread-max?

使用此代码:

void yield_sleep(void)
{
    using namespace std::chrono;

    static size_t thread_num;

    auto start{high_resolution_clock::now()};
    std::this_thread::yield();
    auto end{high_resolution_clock::now()};

    std::cout << thread_num++
              << "|Waiting for: "
              << duration_cast<microseconds>(end - start).count()
              << " ms."
              << std::endl;
}

int main(void)
{
    std::vector<std::thread> tp(62434);

    std::generate(tp.begin(), tp.end(), []() { return std::thread(yield_sleep); });
    std::for_each(tp.begin(), tp.end(), [](auto& t) { t.join(); });
}
Run Code Online (Sandbox Code Playgroud)

程序创建 ~32718 线程并抛出异常:

terminate called after throwing an instance of 'std::system_error'
  what():  Resource temporarily unavailable
Run Code Online (Sandbox Code Playgroud)

但是里面/proc/sys/kernel/threads-max的值是62434。有什么问题?为什么我的程序在创建线程期间抛出异常?

c++ multithreading gcc gcc9

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

当声明为 long 的文字分配给 c 中的 int 时,gcc 是否没有警告?

我可以编译并运行一个程序,该程序将一个 long int 文字(尽管它适合 int)分配给 int 变量。

$ cat assign-long-to-int.c
#include <stdio.h>

int main(void){
  int i = 1234L;        //assign long to an int
  printf("i: %d\n", i);
  return 0;
}
$ gcc assign-long-to-int.c -o assign-long-to-int
$ ./assign-long-to-int 
i: 1234
Run Code Online (Sandbox Code Playgroud)

我知道 1234 适合 int,但仍然希望能够启用警告。我已经浏览了所有gcc 选项,但找不到任何合适的。

是否可以针对这种情况生成警告?从这里的讨论和 gcc 选项来看,简短的答案是否定的。这是不可能的。

这样的警告还有意义吗?在我发布的简单示例中,很明显 1234L 被分配给 int 变量,并且它适合。但是,如果声明和赋值被多行代码分隔开怎么办?编写 1234L 的程序员表示他们希望将这个字面整数分配给 long。否则,附加 L 有何意义?

在某些情况下,附加 L 确实会产生影响。例如

$ cat sizeof-test.c 
#include <stdio.h>
void main(void){
  printf("%ld\n", sizeof(1234));
  printf("%ld\n", sizeof(1234L));
}
$ ./sizeof-test 
4
8
Run Code Online (Sandbox Code Playgroud)

尽管编译器必须知道 1234L 适合 …

c gcc gcc-warning gcc9

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

在哪里可以找到 std::chrono::system_clock::now() 的 GCC 9 实现?

系统chrono头 ( /usr/include/c++/9/chrono) 声明但不定义static now()其时钟的功能。我也没有看到看起来相关的包含内容。这些功能是在哪里实现的呢?

c++ system-clock c++-chrono gcc9

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

使用 std::cout 打印 #define 宏

我正在尝试这样做

#define _TEST_ test
#include <iostream>

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

据我了解,我期望这个输出。

test
Run Code Online (Sandbox Code Playgroud)

但是,我得到的输出是

_TEST_
Run Code Online (Sandbox Code Playgroud)

为什么我在这里做错了?

c++ gcc9

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