diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 71efbb40d33abb09fb6ef31497236e0c466dceb3..030cce92c539187592223913be635a566aa4f648 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,7 +32,6 @@ if (MSVC)
     # /Zc:inline          - Let codegen omit inline functions in object files
     # /Zc:throwingNew     - Let codegen assume `operator new` (without std::nothrow) will never return null
     add_compile_options(
-        /W3
         /MP
         /Zi
         /Zo
@@ -43,6 +42,14 @@ if (MSVC)
         /Zc:externConstexpr
         /Zc:inline
         /Zc:throwingNew
+
+        # Warnings
+        /W3
+        /we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect
+        /we4548 # Expression before comma has no effect; expected expression with side-effect
+        /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
+        /we4555 # Expression has no effect; expected expression with side-effect
+        /we4834 # Discarding return value of function with 'nodiscard' attribute
     )
 
     # /GS- - No stack buffer overflow checks
@@ -56,6 +63,7 @@ else()
         -Werror=implicit-fallthrough
         -Werror=missing-declarations
         -Werror=reorder
+        -Werror=unused-result
         -Wextra
         -Wmissing-declarations
         -Wno-attributes
diff --git a/src/common/file_util.h b/src/common/file_util.h
index 8b587320f26863aa2c378c435780bb8e477c05b6..840cde2a68c10b79ad1515e6e0ca00d122ce1024 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -232,7 +232,7 @@ public:
 
     void Swap(IOFile& other) noexcept;
 
-    [[nodiscard]] bool Open(const std::string& filename, const char openmode[], int flags = 0);
+    bool Open(const std::string& filename, const char openmode[], int flags = 0);
     bool Close();
 
     template <typename T>
diff --git a/src/common/misc.cpp b/src/common/misc.cpp
index 68cb86cd1379335c72a03f9da468d97f91ad85cb..1d5393597c34fabc4432fc24e48d63c8370d0e18 100644
--- a/src/common/misc.cpp
+++ b/src/common/misc.cpp
@@ -16,16 +16,23 @@
 // Call directly after the command or use the error num.
 // This function might change the error code.
 std::string GetLastErrorMsg() {
-    static const std::size_t buff_size = 255;
+    static constexpr std::size_t buff_size = 255;
     char err_str[buff_size];
 
 #ifdef _WIN32
     FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(),
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_str, buff_size, nullptr);
+    return std::string(err_str, buff_size);
+#elif defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600))
+    // Thread safe (GNU-specific)
+    const char* str = strerror_r(errno, err_str, buff_size);
+    return std::string(str);
 #else
     // Thread safe (XSI-compliant)
-    strerror_r(errno, err_str, buff_size);
+    const int success = strerror_r(errno, err_str, buff_size);
+    if (success != 0) {
+        return {};
+    }
+    return std::string(err_str);
 #endif
-
-    return std::string(err_str, buff_size);
 }