我找到了很多有关静态的文章(MSDN,MSDN 2,Stack Overflow等等),但是我仍然不明白为什么此代码返回-1:
class Program
{
static int value = 0;
static int foo()
{
value = value - 7;
return 1;
}
static void Main(string[] args)
{
value -= foo();
Console.WriteLine(value);
Console.ReadKey();
}
}
Run Code Online (Sandbox Code Playgroud)
这是调试器在foo()运行后但从中减去结果之前显示的内容value:
但是,下一步value是-1:
我希望-8因为静态字段存储在内存中一次。
当我将其更改为
var x = foo();
value -= x;
Run Code Online (Sandbox Code Playgroud)
表明 -8
究竟如何运作?
C ++ 20引入的属性[[likely]]和[[unlikely]]该语言,其可以被用于允许编译器优化为的情况下一个执行路径或者多更容易或远小于可能比其他的。
考虑到错误分支预测的成本,这似乎是一个在代码的性能关键部分可能非常有用的功能,但我不知道它实际上会导致编译器做什么。
是否有一段简单的代码可以添加[[likely]]和[[unlikely]]属性更改编译器的程序集输出?也许更重要的是,这些变化有什么作用?
我为自己的理解创建了一个简单的示例,以查看程序集是否有任何差异,但似乎这个示例太简单了,无法实际显示对程序集的任何更改:
void true_path();
void false_path();
void foo(int i) {
if(i) {
true_path();
} else {
false_path();
}
}
void bar(int i) {
if(i) [[likely]] {
true_path();
} else [[unlikely]] {
false_path();
}
}
Run Code Online (Sandbox Code Playgroud)
Suppose I have
template<int ...>
struct Ints { };
class MyClass
{
public:
Ints<1, 2, 3> get() { return Ints<1, 2, 3>(); }
};
Run Code Online (Sandbox Code Playgroud)
What I want to do is simple.
template <class T>
vector<int> MyFunc1(T& x)
{
Ints<S...> result = x.get();
vector<int> t = { S... };
return t;
}
Run Code Online (Sandbox Code Playgroud)
Somewhat like this. (Here MyClass can be one example of T.) Apparently, for compiler S... seems to invalid.
template <class T, int... S>
vector<int> MyFunc2(T& x)
{
Ints<S...> …Run Code Online (Sandbox Code Playgroud) 我一直在使用clang格式来帮助保持我的代码干净.对于多行函数调用,有没有办法让clang将克隆括号放在它自己的行上?
例:
现在正在做什么:
increment_and_call_on_match(
clique_colors,
0,
max_clique_color,
[&](int clique_color) {
comms.emplace_back(context.split_by_color(clique_color));
},
[&](int) { context.split_by_color(); });
Run Code Online (Sandbox Code Playgroud)
我想要的是:
increment_and_call_on_match(
clique_colors,
0,
max_clique_color,
[&](int clique_color) {
comms.emplace_back(context.split_by_color(clique_color));
},
[&](int) { context.split_by_color(); }
); //Closing paren on new line
Run Code Online (Sandbox Code Playgroud) 我正在用 C++ 编写一个库,它实现了一些不同的协程原语,该库针对的是新发布的 C++20。因此,它还利用了诸如在 C++20 中添加到语言中的概念之类的东西。
我想使用 github 操作来构建库,但构建失败,因为ubuntu-latest使用 GCC 9 和 CLang 9,但我的库至少需要 GCC 10 或 Clang 10 才能构建。
我尝试通过设置来配置构建操作-DCMAKE_CXX_COMPILER=g++-10,但该操作在配置 CMake 阶段失败,因为在系统上找不到 g++-10。
有什么方法可以指定 github 操作应该使用 GCC 10 还是 Clang 10?
这是我尝试运行的最新工作流文件:
name: CMake
on: [push]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert …Run Code Online (Sandbox Code Playgroud) 在工作中,我一直在使用Linux和CCC 11和C++ 14的GCC编译器.在一些工作代码中,我使用了一个联合来存储引用和指针,如下所示:(简化为重要部分)
struct MyStruct
{
//Stuff
union { double& x; double* x_ptr; };
MyStruct(double& value) : x(value) {}
//More stuff
};
Run Code Online (Sandbox Code Playgroud)
我相信这段代码清晰,可读,明确,并提供了一种方便的方式来存储可以转移到其他东西的引用.它提供易于理解的语法糖,而不会降低性能,同时提高可读性.但是,当我尝试在visual studio 15中使用这样的代码时,代码由于"double&的非法联合成员"而无法编译.
注意:在我的工作中,几乎所有代码都是为Linux编写的,并使用GCC编译,对于我的特定项目,C++ 11是有保证的,GCC是唯一将要使用的编译器.
编辑:请不要告诉我在联盟内部引用"没有意义".当引用存储在结构中时,它占用与指针相同的空间量.另外,以下用clang编译:
struct MyStruct
{
//This will compile
union
{
struct { double& x; };
double* x_ptr;
};
//This won't compile; WHY?
/*union
{
double& x;
double* x_ptr;
};*/
MyStruct(double& val) : x(val){}
void Repoint(double& new_value)
{
x_ptr = &new_value;
}
};
Run Code Online (Sandbox Code Playgroud)
为什么它在引用包装在匿名结构中时编译,而不是在它只是在联合中?
如何printf从浮点数中提取数字等函数?我理解原则上可以做到这一点.给定一个x你希望得到第一个n数字的数字,x用10的幂来缩放,这x是在pow(10, n)和之间pow(10, n-1).然后转换x为整数,并取整数的数字.
我尝试了这个,它有效.有点.我的答案与printf前16个十进制数字给出的答案相同,但之后的答案往往不同.怎么printf做?
假设这T是一个不包含指针的POD类型,我想序列化T(除了一些其他数据).我创建了以下函数来执行此操作:
template<class T> void serialize(const T& source, char*& dest)
{
*(T*)dest = source;
dest += sizeof(T);
}
template<class T> void deserialize(T& dest, char*& source)
{
dest = *(T*)source;
source += sizeof(T);
}
Run Code Online (Sandbox Code Playgroud)
这会导致任何问题,还是有任何编译器无法解决问题?换句话说,代码是:
template<class T> bool check_sanity(const T& obj)
{
std::unique_ptr<char[]> buffer { new int[sizeof(T)] };
serialize(obj, buffer);
T new_obj;
deserialize(new_obj, buffer);
return new_obj == obj;
}
Run Code Online (Sandbox Code Playgroud)
曾经回归虚假?(假设T是POD,没有人重载==运算符).
我正在编写这些序列化方法以与MPI一起使用,它们将在程序开始时用于分发簿记所需的一些数据,因此相同的程序将始终对数据进行序列化和反序列化.
所以最近学习了perflinux中的命令。我决定进行一些实验,因此我创建了一个空的 C 程序并测量了运行所需的指令数:
echo 'int main(){}'>emptyprogram.c && gcc -O3 emptyprogram.c -o empty
perf stat ./empty
Run Code Online (Sandbox Code Playgroud)
这是输出:
Performance counter stats for './empty':
0.341833 task-clock (msec) # 0.678 CPUs utilized
0 context-switches # 0.000 K/sec
0 cpu-migrations # 0.000 K/sec
112 page-faults # 0.328 M/sec
1,187,561 cycles # 3.474 GHz
1,550,924 instructions # 1.31 insn per cycle
293,281 branches # 857.966 M/sec
4,942 branch-misses # 1.69% of all branches
0.000504121 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)
为什么它使用这么多指令来运行一个实际上什么也不做的程序?我认为这可能是将程序加载到操作系统中所需的一些基准指令数,因此我寻找了用汇编语言编写的最小可执行文件,并且发现了一个在此处输出的 142 字节可执行文件"Hi World"(http://timelessname.txt)。 …
我正在使用MPI进行高性能计算中的C ++项目。我有一个函数,其中包含一些不同的重载,可用于将不同的类型转换为字符串:
void append(std::string& s, int value);
void append(std::string& s, void* value);
void append(std::string& s, MPI_Request request);
Run Code Online (Sandbox Code Playgroud)
当我使用Open MPI时,这工作正常。在OpenMPI中,MPI_Request是的别名ompi_request_t*,因此每个重载都有不同的签名。
但是,最近,我尝试使用MPICH编译代码。在MPICH中,MPI_Request是的别名int,结果是上述代码由于两次append定义而无法编译int:
/home/me/NimbleSM/src/mpi-buckets/src/mpi_err.hpp: At global scope:
/home/me/NimbleSM/src/mpi-buckets/src/mpi_err.hpp:28:6: error: redefinition of ‘void append(std::__cxx11::string&, int)’
void append(std::string& s, int i) { s.append(std::to_string(i)); }
^~~
/home/me/NimbleSM/src/mpi-buckets/src/mpi_err.hpp:17:6: note: ‘void append(std::__cxx11::string&, MPI_Request)’ previously defined here
void append(std::string& s, MPI_Request request)
Run Code Online (Sandbox Code Playgroud)
我应该如何编写append(std::string&, MPI_Request),以使编译器在MPI_Request定义为时忽略它int,而在MPI_Request是库类型时识别它?
enable_if失败 …