Parsing precedence of #pragma statements #pragma


Carl Hoefs
 

Xcode 10.0, iOS 12.0.1, ObjC

I have a common include file for my project that defines some structs that need to be packed/aligned a certain way, so it includes the following statement:

#pragma pack(4)

However, Xcode generates a "#pragma pack alignment value is modified" warning for each time the include file is referenced.

I've tried to apply the following "#include guard" to the pragma statement:

#ifndef __PACKED
#define __PACKED
#pragma pack(4)
#endif

But Xcode seems to scan for and execute #pragma statements before #if's, generating the same warnings.

Is there a way to cause Xcode to execute a #pragma statement only once?

-Carl


 



On Oct 9, 2018, at 12:40 PM, Carl Hoefs <newslists@...> wrote:

However, Xcode generates a "#pragma pack alignment value is modified" warning for each time the include file is referenced.

It’s a good idea to put #pragma once at the top of every header file, to ensure that it won’t be included more than once. This will speed up compiles and prevent errors about duplicate symbols, etc.

#pragma pack(4)

You should be pushing/popping the pack state — otherwise it persists for all subsequent declarations and will alter every declared struct’s layout. This will likely cause strange crashes due to inconsistencies between struct field offsets.

(I looked around for a reference on how to use push/pop with #pragma pack in Clang, but drew a blank, sorry. Anyone else remember the syntax?)

—Jens


Steve Mills
 

On Oct 10, 2018, at 12:32:14, Jens Alfke <jens@mooseyard.com> wrote:


It’s a good idea to put #pragma once at the top of every header file, to ensure that it won’t be included more than once. This will speed up compiles and prevent errors about duplicate symbols, etc.
But it's not a standard directive, so only use it if you know your files will only be compiled on compilers that support it. I.e. don't use it in files shared with other platforms. A better way to handle it is:

#if !defined(thisfile_h) // or #ifndef thisfile_h if you prefer a less readable form.
#define thisfile_h

Everything for thisfile.h goes inside here

#endif

--
Steve Mills
Drummer, Mac geek


Carl Hoefs
 

On Oct 10, 2018, at 10:55 AM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

But it's not a standard directive, so only use it if you know your files will only be compiled on compilers that support it. I.e. don't use it in files shared with other platforms.
Agreed.

A better way to handle it is:

#if !defined(thisfile_h) // or #ifndef thisfile_h if you prefer a less readable form.
#define thisfile_h

Everything for thisfile.h goes inside here

#endif
The problem with this is that Xcode seems to scan and process the #pragma directives regardless of any enclosing #if directive.

-Carl


Carl Hoefs
 


On Oct 10, 2018, at 10:32 AM, Jens Alfke <jens@...> wrote:

You should be pushing/popping the pack state — otherwise it persists for all subsequent declarations and will alter every declared struct’s layout. This will likely cause strange crashes due to inconsistencies between struct field offsets.


Yes, I had forgotten about this! I've actually done this before (pushing/popping the stack state), long ago. But I can't seem come up with the correct syntax for it now...

-Carl


 



On Oct 10, 2018, at 10:55 AM, Steve Mills via Groups.Io <sjmills@...> wrote:

But it's not a standard directive, so only use it if you know your files will only be compiled on compilers that support it. I.e. don't use it in files shared with other platforms. A better way to handle it is:

It’s not ANSI standard, but it’s supported by Clang, GCC and MSVC, which are all the mainstream C[++] compilers I know of. I manage a codebase that has to run on Apple platforms, Linux, Android, Windows, and various embedded CPUs, and we use #pragma once with impunity.

The alternative you suggest works too, but it creates additional boilerplate and is [slightly] slower to compile since the header does have to be opened and partially preprocessed every time something tries to #include it.

—Jens


Carl Hoefs
 


On Oct 10, 2018, at 12:41 PM, Carl Hoefs <newslists@...> wrote:


On Oct 10, 2018, at 10:32 AM, Jens Alfke <jens@...> wrote:

You should be pushing/popping the pack state — otherwise it persists for all subsequent declarations and will alter every declared struct’s layout. This will likely cause strange crashes due to inconsistencies between struct field offsets.


Yes, I had forgotten about this! I've actually done this before (pushing/popping the stack state), long ago. But I can't seem come up with the correct syntax for it now...

I think I found it.

#pragma options align=reset

Thanks to all.
-Carl