Skip to content

Commit a3eeef7

Browse files
committed
Scope the base_macros.h warning disables to base.h
base_macros.h disables C5046, C4268, C4499 and C4630 without a matching #pragma warning(push)/(pop) pair. base.h includes it near the top and never restores the warning state, so those four warnings stay disabled for the rest of every translation unit that includes base.h, not just for the C++/WinRT declarations they were added for. Consumers silently lose the warnings in their own code: namespace { struct S { int x; }; } S f(); int main() { f(); } That warns C5046 on its own, and stops warning as soon as <winrt/base.h> is included ahead of it, at both /W4 and /Wall. Open the scope before the include and close it at the end of base.h. The disables still cover everything C++/WinRT declares, and the warning state is handed back to the consumer unchanged. The set of warnings reported from within the C++/WinRT headers is unaffected.
1 parent 856eaff commit a3eeef7

3 files changed

Lines changed: 33 additions & 0 deletions

File tree

‎cppwinrt/code_writers.h‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,33 @@ namespace cppwinrt
117117
return { w, write_close_file_guard };
118118
}
119119

120+
static void write_macro_warning_pop(writer& w)
121+
{
122+
auto format = R"(#ifdef _MSC_VER
123+
#pragma warning(pop)
124+
#endif // _MSC_VER
125+
)";
126+
127+
w.write(format);
128+
}
129+
130+
// base_macros.h disables a handful of compiler warnings that C++/WinRT's own
131+
// declarations would otherwise trigger. Those disables have to stay in effect
132+
// for the rest of the file that includes it, so the enclosing scope is opened
133+
// here rather than inside base_macros.h itself. Without the matching pop the
134+
// disables would remain active for everything the consumer writes after the
135+
// include, silently turning the warnings off for their code as well.
136+
[[nodiscard]] static finish_with wrap_macro_warning_scope(writer& w)
137+
{
138+
auto format = R"(#ifdef _MSC_VER
139+
#pragma warning(push)
140+
#endif // _MSC_VER
141+
)";
142+
143+
w.write(format);
144+
return { w, write_macro_warning_pop };
145+
}
146+
120147
[[nodiscard]] static finish_with wrap_lean_and_mean(writer& w, bool is_lean_and_mean = true)
121148
{
122149
if (is_lean_and_mean)

‎cppwinrt/file_writers.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace cppwinrt
1717
w.write(strings::base_detect_numerics);
1818
w.write(strings::base_include_numerics);
1919
}
20+
auto wrap_macro_warnings = wrap_macro_warning_scope(w);
2021
w.write_root_include("base_macros");
2122
w.write(strings::base_source_location);
2223
w.write(strings::base_types);

‎strings/base_macros.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
#define WINRT_IMPL_SHIM(...) (*(abi_t<__VA_ARGS__>**)&static_cast<__VA_ARGS__ const&>(static_cast<D const&>(*this)))
2424

2525
#ifdef _MSC_VER
26+
// These disables deliberately apply to the remainder of the file that includes
27+
// this header, because they cover declarations made throughout C++/WinRT. The
28+
// including file opens a #pragma warning(push) beforehand and pops it at the
29+
// end, which keeps them from escaping into consumer code.
30+
2631
// Note: this is a workaround for a false-positive warning produced by the Visual C++ 15.9 compiler.
2732
#pragma warning(disable : 5046)
2833

0 commit comments

Comments
 (0)