在玩VS11测试版的时候,我注意到了一些奇怪的东西:这个代码couts
f耗时0毫秒
int main()
{
std::vector<int> v;
size_t length =64*1024*1024;
for (int i = 0; i < length; i++)
{
v.push_back(rand());
}
uint64_t sum=0;
auto t1 = std::chrono::system_clock::now();
for (size_t i=0;i<v.size();++i)
sum+=v[i];
//std::cout << sum << std::endl;
auto t2 = std::chrono::system_clock::now();
std::cout << "f() took "
<< std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count()
<< " milliseconds\n";
}
Run Code Online (Sandbox Code Playgroud)
但是,当我决定取消注释总和时,它打印出一个合理的数字.
这是我启用优化后的行为,禁用它们我得到"正常"cout
f()花了471毫秒
这个符合标准的行为是什么?重要提示:不是死代码被优化掉了,我可以看到从控制台运行时的滞后,我可以看到任务管理器中的CPU峰值.
如果标题听起来很奇怪,这是另一种解释:
如果我有一个范围的一个,我想指望其它范围内进行了多少次b出现在范围一,有没有一个std::函数来做到这一点?
如果不是,有没有一种简单的方法(我可以手动循环使用std::search- 我说的是更优雅的东西)?
如果我的内部类是我自己的版本vector<char>(我控制源)并且为了示例我不能改变它std::string是否有一种方法来窃取内存std::string,就像移动构造函数std::string一样.
所以像这样:
std::string str{"abcdefghijklmnopqrstu"};
MyVectorCharClass mvc(std::move(str)); // Constructor takes memory from str
Run Code Online (Sandbox Code Playgroud)
我想我听到的一些建议,未来要添加.release()到std::string或std::vector,但我说的是现在.
我最近阅读了很酷的文章:https: //akrzemi1.wordpress.com/2015/08/20/can-you-see-the-bug/在ideone上使用简化版本我得到了令人惊讶的行为:
#include <iostream>
#include <cassert>
using namespace std;
int main() {
const size_t sz=258;
string s{sz,'#'};
assert(2==s.size());
}
Run Code Online (Sandbox Code Playgroud)
不编译,但与const删除编译相同的程序:
#include <iostream>
#include <cassert>
using namespace std;
int main() {
size_t sz=258;
string s{sz,'#'};
assert(2==s.size());
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是这个标准要求或只是编译器决定一个是编译器警告而另一个是编译器错误.
如果它有帮助,这里是gcc 5.1(tnx godbolt)的错误和警告
!!错误:缩小'258ul'从'size_t {aka long unsigned int}'到'char'的转换{}
!!警告:缩小'sz'从'size_t {aka long unsigned int}'转换为'char'的内部{} [-Wnarrowing]
好人铿锵3.6在这两种情况下都给出了错误,但问题仍然存在,是一个合法而糟糕的C++和其他非法C++?
我正在观看视频,其中Nicolai说自动失去移动语义为此示例:
template<typename Callable, typename... Args>
auto call(Callable&& op, Args&&... args) {
return std::invoke(std::forward<Callable>(op), std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
我在想:
这是为什么?
在这个例子中确实保证了 RVO的启动吗?如果是这样,有什么担心搬家的?
CMake 有一个令人恼火的默认行为(我想,我在 CMake 配置中没有看到任何神奇的东西,但我可能是错的,因为我对 CMake 知之甚少),当您将目标添加到项目中时,即使该目标不存在,他也会默默地忽略该行为存在,例如:
项目(堆栈溢出)
// 另一个 CMakeLists.txt
项目(东西)
target_link_libraries(Stuff PUBLIC StackOverlow)
有没有办法强制 CMake 检查您链接的所有项目都target_link_libraries必须存在?
我有一种情况,其中2个不同的进程(我的C++,其他由JAVA中的其他人完成)是来自某些共享数据文件的编写者和读者.所以我试图通过编写这样的类来避免竞争条件(编辑:这个代码坏了,它只是一个例子)
class ReadStatus
{
bool canRead;
public:
ReadStatus()
{
if (filesystem::exists(noReadFileName))
{
canRead = false;
return;
}
ofstream noWriteFile;
noWriteFile.open (noWriteFileName.c_str());
if ( ! noWriteFile.is_open())
{
canRead = false;
return;
}
boost::this_thread::sleep(boost::posix_time::seconds(1));
if (filesystem::exists(noReadFileName))
{
filesystem::remove(noWriteFileName);
canRead= false;
return;
}
canRead= true;
}
~ReadStatus()
{
if (filesystem::exists(noWriteFileName))
filesystem::remove(noWriteFileName);
}
inline bool OKToRead()
{
return canRead;
}
};
Run Code Online (Sandbox Code Playgroud)
用法:
ReadStatus readStatus; //RAII FTW
if ( ! readStatus.OKToRead())
return;
Run Code Online (Sandbox Code Playgroud)
这是一个程序ofc,其他将有类似的类.想法是:1.检查其他程序是否创建了他的"我是所有者文件",如果它已经中断,则转到2. 2.创建我的"我是所有者"文件,再次检查其他程序是否创建了自己的,如果它已删除我的文件并打破其他,请转到3. 3.执行我的阅读,然后删除我的"我是所有者文件".
请注意,当它们都不读或写时很少出现,但问题是我仍然看到竞争条件的可能性很小,因为理论上其他程序可以检查我的锁文件的存在,看到没有一个,然后我创建了我的,其他程序创建了自己的程序,但在FS创建他的文件之前我再次检查,它不存在,然后发生灾难.这就是为什么我添加了一秒延迟,但作为CS书呆子,我发现让代码运行起来令人不安.Ofc我不希望这里的任何人给我写一个解决方案,但如果有人知道我可以使用的可靠代码的链接,我会很高兴.PS它必须是文件,因为我不是在编写整个项目,而是它是如何安排完成的.
PPS:访问数据文件不是读者,作者,读者,作家....它可以是读者,读者,作家,作家,作家,读者,作家....
PPS:其他进程不是用C++编写的:(因此提升是不可能的.
我对C++ fmtlib的这个简短函数如何工作有点困惑.
inline std::uint32_t digits10_clz(std::uint32_t n) {
std::uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12;
return t - (n < powers_of_10_u32[t]) + 1;
}
Run Code Online (Sandbox Code Playgroud)
我理解你可以使用log2(log10)来估计log10的逻辑,并且你需要调整精确值,但乘法对我来说是一个谜.
我很困惑与问候如何编译和链接处理的事实,在电话会议上要求ER功能的依靠,如果函数使用静脉阻塞或NRVO不同.
这可能是我的误解,但我的假设是通常没有RVO或NRVO
std::string s = get_string();
Run Code Online (Sandbox Code Playgroud)
如果get_string不执行N?RVO但是如果get_string执行N?RVO调用代码什么也不做,并且s由函数get_string构造到位,则涉及从get_string的结果移动构造s .
编辑:这是我如何设想get_string调用程序操作,如果没有N?RVO:
现在还有RVO
我知道这艘船由于需要 ABI 损坏而已经航行,但我想知道为什么最初的实现没有决定使用一些神奇的位模式std::string来std::vector表示空的可选值。这显然需要类型的位表示中的一些“自由”值,因此例如它不适用于int,size_t但许多复杂类型具有某些永远不会出现在有效实例中的表示。
C++ 甚至可以指定某种方式来选择您的类型,例如通过专门化
std::nullopt_sentinel
Run Code Online (Sandbox Code Playgroud)
对于用户定义的类型。
我最好的猜测是,指定/实现这个的复杂性(因为您需要为许多类型实现哨兵std::)比总是使用 bool 要大得多,但我想知道是否还有其他原因。
Rust 的类似答案似乎有时会实现这一点
c++ ×9
c++11 ×2
optimization ×2
abi ×1
auto ×1
c++-chrono ×1
c++17 ×1
clang ×1
cmake ×1
filesystems ×1
fmt ×1
gcc ×1
nrvo ×1
rvo ×1
stdoptional ×1
stl ×1
templates ×1
unsigned ×1