我实现了一个线程安全的共享库。为了保护我使用的关键区域 std::lock_guard<std::mutex>
来自 C++11 标准。
打字错误是我省略了对象本身:
std::lock_guard<std::mutex>(getMutexObj());
代替
std::lock_guard<std::mutex> lock_obj(getMutexObj());
然后将它复制/粘贴到每个地方...不用说,当多线程应用程序开始不可预测地崩溃时,我花了一段时间才找到它的根源。
为了涵盖所有要点,getMutexObj()
的声明和互斥量本身如下:
...
mutable std::mutex m_mutex;
...
std::mutex& getMutexObj() const
{
return m_mutex;
}
所有代码都是用g++ 5.2.0
编译的带有以下警告标志:
WARNINGS := -pedantic \
-Wall \
-Wextra \
-Werror \
-Wconversion \
-Woverloaded-virtual \
-Wcast-qual \
-Wctor-dtor-privacy \
-Wdisabled-optimization \
-Wuninitialized \
-Wformat=2 \
-Winit-self \
-Wlogical-op \
-Wmissing-declarations \
-Wmissing-include-dirs \
-Wold-style-cast \
-Wredundant-decls \
-Wshadow \
-Wsign-conversion \
-Wsign-promo \
-Wstrict-null-sentinel \
-Wstrict-overflow=5 \
-Wswitch-default \
-Wundef \
-Wunused \
-Wfloat-equal \
-Wsuggest-final-methods \
-Wsuggest-final-types \
-Wzero-as-null-pointer-constant
为什么编译器没有在 std::lock_guard<std::mutex>(getMutexObj());
上发出任何警告? ?
我尝试了下面的代码只是为了看看编译器是否对它们抛出警告:
std::lock_guard<std::mutex>(getMutexObj());
int(23);
23;
uint16_t remove_me = 23;
对于第 2、3 和 4 行,我收到了警告,但对于第 1 行却没有...为什么?
<.../path/...>:32:16: error: statement has no effect [-Werror=unused-value]
int(23);
^
<.../path/...>:33:11: error: statement has no effect [-Werror=unused-value]
23;
^
<.../path/...>:34:18: error: unused variable 'remove_me' [-Werror=unused-variable]
uint16_t remove_me = 23;
^
cc1plus: all warnings being treated as errors
编辑1
我注意到这个问题有点令人困惑,因为几乎所有的答案都与
for line 2,3 and 4 I got warnings BUT not for line 1... WHY?
然而这里真正的问题是:
为什么编译器没有在 std::lock_guard<std::mutex>(getMutexObj());
上发出任何警告? ?
是否有任何开关可以让编译器对此类代码发出警告???
EDIT2
正如 cpplearner 在他的评论中提到的,std::lock_guard<std::mutex>(getMutexObj());
被视为名为 getMutexObj
的函数的函数声明返回 std::lock_guard<std::mutex>
.
我查看了反汇编,发现在 std::lock_guard<std::mutex>(getMutexObj());
的情况下, 根本没有相关的操作码。
但是当我把它改成
std::lock_guard<std::mutex>{getMutexObj()};
并查看反汇编,它被编译为临时对象创建但同样没有任何警告。
最佳答案
不同于 23;
的消息 “错误:语句无效”,创建一个未命名的临时 lock_guard
确实 em> 具有锁定和解锁互斥体的作用。
这具有对其他线程可见的内存屏障的副作用。
关于c++ - 为什么 "constructor invocation"不触发任何编译器 (g++) 警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35431651/