我正在尝试将文件的修改时间格式化为字符串 (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)::clock
and 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) 这个程序(用选项编译-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) 我只是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) 众所周知,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) 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] 的情况下摆脱此警告
我正在尝试将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) 使用此代码:
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。有什么问题?为什么我的程序在创建线程期间抛出异常?
我可以编译并运行一个程序,该程序将一个 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 适合 …
系统chrono
头 ( /usr/include/c++/9/chrono
) 声明但不定义static
now()
其时钟的功能。我也没有看到看起来相关的包含内容。这些功能是在哪里实现的呢?
我正在尝试这样做
#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)
为什么我在这里做错了?
gcc9 ×10
c++ ×6
gcc ×5
c ×3
gcc-warning ×2
avx2 ×1
c++-chrono ×1
c++20 ×1
gcc11 ×1
linker ×1
stdstring ×1
struct ×1
system-clock ×1