poppack.h wrong? - c++

i got a Project to go on coding, so its not my code till now and i can´t explain the following warning message in VS2008 compiling my code:
Warnung 2 warning C4161: #pragma
pack(pop...): Mehr pop- als
push-Vorgänge c:\programme\microsoft
sdks\windows\v6.0a\include\poppack.h 29
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
poppack.h
Abstract:
This file turns packing of structures off. (That is, it enables
automatic alignment of structure fields.) An include file is needed
because various compilers do this in different ways.
poppack.h is the complement to pshpack?.h. An inclusion of poppack.h
MUST ALWAYS be preceded by an inclusion of one of pshpack?.h, in one-to-one
correspondence.
For Microsoft compatible compilers, this file uses the pop option
to the pack pragma so that it can restore the previous saved by the
pshpack?.h include file.
--*/
#if ! (defined(lint) || defined(RC_INVOKED))
#if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
#pragma warning(disable:4103)
#if !(defined( MIDL_PASS )) || defined( __midl )
#pragma pack(pop)
#else
#pragma pack()
#endif
#else
#pragma pack()
#endif
#endif // ! (defined(lint) || defined(RC_INVOKED))
Can you explain why? Isnt this a Microsoft File?

You need to make sure that you match every
#include <pshpack.h>
with a use of
#include <poppack.h>
If my German is serving me right, it's complaining about a mis-match.

It seems that you must include pshpack.h at the beginning of your code, and include poppack.h at the end.

Related

TYPE_ALIGNMENT(LARGE_INTEGER) incorrect when building against Win10 SDK

I am running into issues with this assertion in the Win 10 SDK for Winnt.h, when upgrading from Win8.1 a C file which #includes winnt.h:
C:\Program Files (x86)\Windows
Kits\10\Include\10.0.18362.0\um\winnt.h(2487,1): error C2118: negative
subscript
#if defined(__cplusplus) && (_MSC_VER >= 1600)
static_assert(__alignof(LARGE_INTEGER) == 8, "Windows headers require the default packing option. Changing this can lead to memory corruption."
" This diagnostic can be disabled by building with WINDOWS_IGNORE_PACKING_MISMATCH defined.");
#elif _MSC_VER >= 1300
#pragma warning(push)
#pragma warning(disable: 4116)
C_ASSERT(TYPE_ALIGNMENT(LARGE_INTEGER) == 8); <========= LN2487
#pragma warning(pop)
#endif
#endif
The error is simply telling me the CASSERT failed, but I have explicitly set /Zp8 and that made no difference.
So I hacked Winnt.h:
// Much of the Windows SDK assumes the default packing of structs.
#if !defined(WINDOWS_IGNORE_PACKING_MISMATCH) && !defined(__midl) && !defined(MIDL_PASS) && !defined(SORTPP_PASS) && !defined(RC_INVOKED)
#if defined(__cplusplus) && (_MSC_VER >= 1600)
static_assert(__alignof(LARGE_INTEGER) == 8, "Windows headers require the default packing option. Changing this can lead to memory corruption."
" This diagnostic can be disabled by building with WINDOWS_IGNORE_PACKING_MISMATCH defined.");
#elif _MSC_VER >= 1300
#pragma warning(push)
#pragma warning(disable: 4116)
#pragma pack(show)
C_ASSERT(TYPE_ALIGNMENT(LARGE_INTEGER) == 8);
#pragma warning(pop)
#endif
#endif
Test code:
#pragma pack(show)
#include "LibraryHeader.h" //somehow includes Windows.h
#pragma pack(show)
Now I get result:
value of pragma pack(show) == 8
value of pragma pack(show) == 4
value of pragma pack(show) == 8
So it seems the mess of 3rd party headers we are using must be causing this. Which is weird because it worked against the 8.1 SDK, and because the header itself explcitly tells us we must have 8-byte packing/alignment set in the compiler.
I guess the question comes down to: is there any way the W10 SDK is causing this given no code has changed and it compiles against W8.1 SDK? Or, has it always been like this and the W8.1 SDK failed to check?
The section of Winnt.h posted in the question from Win 10 SDK is missing from the Win8.1 SDK, which implies the issue was always there but unreported.
Microsoft provide a way to disable this check, using the WINDOWS_IGNORE_PACKING_MISMATCH preprocessor definition.
For those interested, I verified in the library that it was indeed pushing/popping packing values for specific machine architectures. I couldn't tell why but that was as deep as I was willing to go!
I ran into this same issue with old C source code that compiled fine with Visual Studio 2017 and earlier but issued the same error with Visual Studio 2019 using the Windows 10 SDK.
My problem was a couple of projects in the solution had explicitly set the Struct Member Alignment compiler option to /Zp1 which resulted in the C_ASSERT failing with the somewhat opaque error of "negative subscript" from include file winnt.h.
This could also be caused by using a pack pragma prior to the include file winnt.h being included or processed by the Preprocessor. See Negative Subscript in winnt.h posted into the Visual Studio Developer Community by someone who was doing that.
I changed the option from /Zp1 to Default and the project compiled fine.
See also Static assertion failed with "Windows headers require the default packing option..." and see as well ERROR Windows headers require the default packing option on winnt.h
See also this Visual Studio Developer Community post, C2118 error with Windows Kits 10.0.18362.0 in winnt.h, which several posts mentioning this seems to be due to a change in the Windows 10 SDK beginning with 10.0.18362.0.
This probably means that some of my structs which depend on a /Zp1 with a byte member alignment are going to create data errors so I have to track those down and use #pragma pack(push, 1) and #pragma pack(pop) where appropriate.
I'm adding this answer in case someone else needs a reminder about this possibility.

how to undefine _MSC_VER?

I work in Visual Studio but my project is for a POSIX-based environment (marmalade sdk). In this project, the release
build is compiled with gcc for ARM but the debug version works on windows and is compiled by MS compiler. Also this environmet has its own implementation of STL and other standard libraries.
Many of these c++ librares have code like this:
#if defined( _MSC_VER )
#include <Windows.h>
#else
#include <pthread.h>
#endif
Is it possible to undefine the _MSC_VER macro? - So that the C++ libraries will detect a POSIX system here.
_MSC_VER is (and always should be) defined when compiling with the Microsoft compiler so that it "evaluates to the major and minor number components of the compiler's version number". Therefore, the code is using the wrong macro test, since it will always be defined to some value for your compiler regardless of the Windows environment differences.
Rather than destroy the definition of _MSC_VER (which could lead to other problems if any code really does want to know the compiler version), what you really should do instead is to correct the condition so that a more appropriate macro test is used that distinguishes between the kinds of Windows environments that you might encounter.
See the more complete list of predefined macros you could consider here
You could either replace the condition ...
#if someOtherConditionGoesHere
... or extend it with additional conditions, e.g.
#if defined(_MSC_VER) && someOtherConditionGoesHere
Of course:
#undef _MSC_VER
#if defined( _MSC_VER )
#include <Windows.h>
#else
#include <pthread.h>
#endif
Or, #undef it before you include the file where _MSC_VER is used.

C++ preprocessor unexpected compilation errors

Please look at the following file: (it is a complete file)
#ifndef TEES_ALGORITHM_LIBRARY_WRAPPER_H
#define TEES_ALGORITHM_LIBRARY_WRAPPER_H
#ifdef _TEES_COMPILE_AS_LIB
#include <dfa\Includes\DFC_algorithms.hpp>
#include <DFA\FuzzyClassifier\FuzzyAlgorithmIntialization\InitFuzzyAlgorithm.hpp>
typedef teesalgorithm::tees_fuzzy_algorithms algorithms_switchyard_class;
#else
#include <DFA\Includes\commercial_algorithms.hpp>
//An incomplete class to hide implementation
class algorithms_switchyard_class;
#endif
class AlgorithmLibraryWrapper {
algorithms_switchyard_class * algorithmPtr_;
typedef teesalgorithm::tees_paramObj paramObj_type;
typedef teesalgorithm::tees_errorObj errorObj_type;
typedef teesalgorithm::tees_statusObj statusObj_type;
typedef teesalgorithm::tees_dataObj dataObj_type;
typedef teesalgorithm::tees_outputObj outputObj_type;
public:
AlgorithmLibraryWrapper(const std::string& sAlgName, paramObj_type& paramObj, errorObj_type& errObj, statusObj_type& statusObj, const char* sFilePath);
static bool dataReader(const std::string& sFileName, dataObj_type& dataObj, errorObj_type& errObj, statusObj_type& statusObj);
bool runalgorithm(const dataObj_type& dataObj, outputObj_type& outObj, errorObj_type& errObj, statusObj_type& statusObj);
~AlgorithmLibraryWrapper();
};
#ifdef _TEES_USE_COMPILED_ALGORITHM_LIB
# ifdef _MSC_VER
#if _MSC_VER < 1400 // If VC 2003
#ifdef _DEBUG
#error No AlgorithmLibWrapper libraries compiled for this version of VC
#else
#error No AlgorithmLibWrapper libraries compiled for this version of VC
#endif
#elif defined(UNDER_CE) // Win CE
#ifdef _DEBUG
#pragma comment( lib, "AlgorithmLibWrapperCEd" )
#else
#pragma comment( lib, "AlgorithmLibWrapperCE" )
#endif
#else // If VC 2005
#ifdef _DEBUG
#pragma comment( lib, "AlgorithmLibWrapperd" )
#else
#pragma comment( lib, "AlgorithmLibWrapper" )
#endif
#endif
#endif
#endif
#endif //TEES_ALGORITHM_LIBRARY_WRAPPER_H
I am getting the following errors; I don't know why. I manually counted the preprocessor directives also.
AlgorithmLibraryWrapper.hpp:10:1: unterminated #ifdef
AlgorithmLibraryWrapper.hpp:7:1: unterminated #ifndef
I am using the poor vxWorks gcc compiler. Please let me know if the fault is mine or the compiler's.
It could be that the problem is in the included files (if there actually are unbalaced #if/#endifs.
I would try preprocessing with another compiler. You can use gcc for that, doesn't matter it wouldn't compile. Just get gcc (or MinGW if you're on Windows) and run
cpp -Iinclude_direcories your_file
Or, if you don't like gcc, get MSVC Express edition. Again, you can preprocess code that even doesn't compile, so no problem with nonworking library etc.
Most compilers have an option that will give you the output from the preprocessor so you can check what it's doing. For example,
gcc -E file.c >file.preproc
will give you the pre-processed source so you can check the balancing of #if against #endif.
At a guess, one of the files you are #including from this one has a mismatched #ifdef/#endif pair. You need to look at all the files (as the preprocesor does), not just this one.
As others have noted, this is most likely due to mismatched include guards.
If the files you are including are under your control (i.e. not part of a 3rd party closed source library), you could consider replacing the #ifndef et. al. guards (which are used to prevent multiple inclusion) with #pragma once. This will eliminate the possibility of having mismatched preprocessor directives.
One caveat of this is that pragma once is non-standard, so it will only work if your compiler supports it.
I have tried to compile your source using vs 6.0 but did not get the error you have mentioned. As others said may be the error is coming from the included header file . For me to get your code compiled i need to comment the above header.
Please check the above header once.
I'd debug this by commenting out sections one by one and trying to identify which section is causing the error.
It could be your compiler does not like the nested #ifdefs or does not interpret the syntax correctly. Maybe it doesn't like the #pragmas.
This is a long shot, but in your source file you have the following line:
# ifdef _MSC_VER
where there is whitespace between the '#' character and the directive name (ifdef). This is valid in C/C++; however, it's not too commonly seen so I wouldn't be very surprised if the odd compiler choked on it.

Weird compile error dealing with Winnt.h

When trying to compile a file that include winnt.h via windows.h, I get the following error:
MyGl.cpp
..\microsoft sdks\windows\v6.0a\include\winnt.h(964) : error C2988: unrecognizable template declaration/definition
..\microsoft sdks\windows\v6.0a\include\winnt.h(964) : error C2059: syntax error : '&'
They point to the following lines in Winnt.h
extern "C++" // templates cannot be declared to have 'C' linkage
template <typename T, size_t N>
char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
Any ideas for what's going on?
My compiler:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
There are at least two ways to do this. The first is to simply include windows.h at the top of all your files. Then include winnt.h only if you need it. However, I find this a bit too much - I don't see the need of including all this goo in every single file.
What I do is this at the very top (first thing) in my C/C++ header files.
#ifndef __wtypes_h__
#include <wtypes.h>
#endif
#ifndef __WINDEF_
#include <windef.h>
#endif
This will get you you the data types, defines, and fundamental Windows API's. You may also need to add the following:
#ifndef _WINUSER_
#include <winuser.h>
#endif
#ifndef __RPC_H__
#include <rpc.h>
#endif
WinNT is a bit of a special animal - don't include it if including the above files works for you. If you do need it, include it after wtypes.h and `windef.h'
If this doesn't work, then check your include paths and predefined macros to see if those might be breaking your build.
Regards, Foredecker

Disabling Warnings generated via _CRT_SECURE_NO_DEPRECATE

What is the best way to disable the warnings generated via _CRT_SECURE_NO_DEPRECATE that allows them to be reinstated with ease and will work across Visual Studio versions?
If you don't want to pollute your source code (after all this warning presents only with Microsoft compiler), add _CRT_SECURE_NO_WARNINGS symbol to your project settings via "Project"->"Properties"->"Configuration properties"->"C/C++"->"Preprocessor"->"Preprocessor definitions".
Also you can define it just before you include a header file which generates this warning.
You should add something like this
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
And just a small remark, make sure you understand what this warning stands for, and maybe, if you don't intend to use other compilers than MSVC, consider using safer version of functions i.e. strcpy_s instead of strcpy.
You could disable the warnings temporarily in places where they appear by using
#pragma warning(push)
#pragma warning(disable: warning-code) //4996 for _CRT_SECURE_NO_WARNINGS equivalent
// deprecated code here
#pragma warning(pop)
so you don't disable all warnings, which can be harmful at times.
i work on a multi platform project, so i can't use _s function and i don't want pollute my code with visual studio specific code.
my solution is disable the warning 4996 on the visual studio project. go to Project -> Properties -> Configuration properties -> C/C++ -> Advanced -> Disable specific warning add the value 4996.
if you use also the mfc and/or atl library (not my case) define before include mfc _AFX_SECURE_NO_DEPRECATE and before include atl _ATL_SECURE_NO_DEPRECATE.
i use this solution across visual studio 2003 and 2005.
p.s. if you use only visual studio the secure template overloads could be a good solution.
You can also use the Secure Template Overloads, they will help you replace the unsecure calls with secure ones anywhere it is possible to easily deduce buffer size (static arrays).
Just add the following:
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
Then fix the remaining warnings by hand, by using the _s functions.
Combination of #[macbirdie] and #[Adrian Borchardt] answer. Which proves to be very useful in production environment (not messing up previously existing warning, especially during cross-platform compile)
#if (_MSC_VER >= 1400) // Check MSC version
#pragma warning(push)
#pragma warning(disable: 4996) // Disable deprecation
#endif
//... // ...
strcat(base, cat); // Sample depreciated code
//... // ...
#if (_MSC_VER >= 1400) // Check MSC version
#pragma warning(pop) // Renable previous depreciations
#endif
For the warning by warning case, It's wise to restore it to default at some point, since you are doing it on a case by case basis.
#pragma warning(disable: 4996) /* Disable deprecation */
// Code that causes it goes here
#pragma warning(default: 4996) /* Restore default */
The best way to do this is by a simple check and assess. I usually do something like this:
#ifndef _DEPRECATION_DISABLE /* One time only */
#define _DEPRECATION_DISABLE /* Disable deprecation true */
#if (_MSC_VER >= 1400) /* Check version */
#pragma warning(disable: 4996) /* Disable deprecation */
#endif /* #if defined(NMEA_WIN) && (_MSC_VER >= 1400) */
#endif /* #ifndef _DEPRECATION_DISABLE */
All that is really required is the following:
#pragma warning(disable: 4996)
Hasn't failed me yet; Hope this helps
you can disable security check. go to
Project -> Properties -> Configuration properties -> C/C++ -> Code Generation -> Security Check
and select Disable Security Check (/GS-)
You can define the _CRT_SECURE_NO_WARNINGS symbol to suppress them and undefine it to reinstate them back.
Another late answer... Here's how Microsoft uses it in their wchar.h. Notice they also disable Warning C6386:
__inline _CRT_INSECURE_DEPRECATE_MEMORY(wmemcpy_s) wchar_t * __CRTDECL
wmemcpy(_Out_opt_cap_(_N) wchar_t *_S1, _In_opt_count_(_N) const wchar_t *_S2, _In_ size_t _N)
{
#pragma warning( push )
#pragma warning( disable : 4996 6386 )
return (wchar_t *)memcpy(_S1, _S2, _N*sizeof(wchar_t));
#pragma warning( pop )
}