Warning equivalent of #pragma poison - ios

I use the crash function for testing Crashlytics integrations, but I obviously never want to ship that code in an app.
It's possible to poison identifiers so that any current or future use causes an error:
#pragma GCC poison crash
Is there an equivalent #pragma directive that emits a warning when an identifier is used? I want to be able to build the codebase while retaining a visible indicator that attention is required.

This should work, now that _Pragma is available. Instead of using #pragma GCC poison, you can just #define the identifier crash in a way which will generate a warning using #pragma GCC warning:
#define DO_PRAGMA(x) _Pragma(#x)
#define WARN(x) DO_PRAGMA(GCC warning #x)
#define crash WARN("crash" used) crash
The first two macros just make it less work to escape quotation marks. Note that crash expands to itself (as well as the _Pragma), which works because the C preprocessor doesn't expand a token inside of its own expansion.
If you change warning to error, you'll get an error instead. You could easily arrange to change all of those by using some more macros, or you could just use -Werror

You could use #warning
Usage would be as follows:
#warning This is a custom message

Related

What is accomplished by checking the address of a constant like SKStoreProductParameterAffiliateToken?

I have this code from a library I am using.
#ifdef __IPHONE_8_0
if (&SKStoreProductParameterAffiliateToken) {
if (self.affiliateToken) {
[appParameters setObject:self.affiliateToken forKey:SKStoreProductParameterAffiliateToken];
if (self.campaignToken) {
[appParameters setObject:self.campaignToken forKey:SKStoreProductParameterCampaignToken];
}
}
}
#endif
Xcode is saying that the first line will always evaluate to be true but what is this line doing exactly? I never saw a if with & and a constant in that way.
SKStoreProductParameterAffiliateToken is defined as
SK_EXTERN NSString * const SKStoreProductParameterAffiliateToken NS_AVAILABLE_IOS(8_0);
What is the developer trying to check, the address of a constant? Is he trying to check if the version of iOS has this constant defined and by doing that, he is trying to check the instruction inside the if should run? But he already has ifdef __IPHONE_8_0... (??!!)
I don't get it.
Anyway I am compiling for iOS 9.3, so I can delete the if and the ifdef, right?
It is a check to see if a weak-linked symbol is available. If the library/framework containing the symbol has been weakly linked and is not available its address will evaluate to NULL and the if condition will be false.
See Using Weakly Linked Methods, Functions, and Symbols in Apple's Using SDK-Based Development for full details.
#ifdef __IPHONE_8_0 checks if Xcode should compile code inside. Ohterwise older version of Xcode will show an error about unknown variable SKStoreProductParameterAffiliateToken.
But when using newer Xcode version (with iOS SDK 8+), we may still can set a lower minimum target for our project. In this case to avoid crash on devices with lower than iOS 8 version we should check first if variable, class, method or function exists.
In your case, we are checking if pointer to SKStoreProductParameterAffiliateToken is not NULL, which means app is currently running at least on iOS 8.

How to trace back #pragma pack?

I've been wrestling with an issue in iOS causing improper allocation, getting less memory back from malloc than I should have for a CPP object. I recently discovered it was due to two translation units including the same header, one of which along its include chain had a few occurrences of #pragma pack.
Now, I'm not sure how to properly trace back to whichever file is using it and ensure that it fixes it. I've added a bunch of #pragma pack(show) and have nailed down the offending file from the top (the offending file being the file that causes others files to have the same pack setting of 1). I've opened that file in Xcode and run preprocess on it.
In most cases, it looks like code is setting pack back to default (8 on arm64). Are there any tools that can help verify which is the offender along the chain?
The only tip that I have (a case of a pack 1, which is what the pack was being set to), is a header from the iOS SDK. But even it looks to be ok.
# 54 "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/usr/include/sys/kauth.h" 2 3 4
#pragma pack(1)
typedef struct {
u_int8_t sid_kind;
u_int8_t sid_authcount;
u_int8_t sid_authority[6];
u_int32_t sid_authorities[16];
} ntsid_t;
#pragma pack()
As I mentioned, when searching through the preprocessed source file, I wasn't able to find any instance of #pragma pack that wasn't undoing its setting shortly after. However, I wasn't aware that there was another way to set packing, via #pragma options align=(packed|reset). It turns out that it wasn't being undone, but I was looking for #pragma pack.

Return statement will never be executed warning

I've recently come across with double return statement (one of them was added by mistake) in our project and wondering why compiler doesn't show a warning for that?!
Ok, I added -Wunreachable-code to other warning flags, but still no luck.
Got warning - with a code to execute after return statement:
Didn't get warning but still second return statement will never be executed.
Even if I add something like this, still no warning
Is there extra warning flag for that, or compiler isn't smart enough?
Good catch!
-Wunreachable-code does not report a warning and there is no other warning flag which would do.
Not even the Static Analyzer catches this mistake!
(Tested with XCode 6.1 GM 2)
Wrap your code in pragma flags that will suppress that warning between the push and pop
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunreachable-code"
//Your code goes here
#pragma GCC diagnostic pop
Use -Wno-unreachable-code for your file in Build Phases.
Try this...
-(NSString*) makeSomeStringForMe {
NSString *someString = #"some string";
return someString;
}

Is there a Clang diagnostic that is only a note?

Clang has several kinds of diagnostics, of which the three main kinds are errors, warnings, and notes.
Notes usually accompany certain warnings and errors, such as duplicate definitions:
error: conflicting types for 'square'
static double square(double x) {
^
note: previous declaration is here
static int square(int x);
^
What I want to know is, does Clang have any diagnostics—especially for Objective-C or C, but I'll settle for C++ if I have to—that consist of only a note, with no associated error or warning?
http://clang.llvm.org/docs/InternalsManual.html#the-diagnostic-kinds-td-files says:
These severities are mapped into a smaller set (the Diagnostic::Level
enum, {Ignored, Note, Warning, Error, Fatal}) of output levels by the
diagnostics subsystem based on various configuration options. Clang
internally supports a fully fine grained mapping mechanism that allows
you to map almost any diagnostic to the output level that you want.
The only diagnostics that cannot be mapped are NOTEs, which always
follow the severity of the previously emitted diagnostic and ERRORs,
which can only be mapped to Fatal (it is not possible to turn an error
into a warning, for example).
So unfortunately no; you can't do that without hacking Clang itself. Notes are intended only for linking to other diagnostics. I'd file a bug with the LLVM tracker; this would definitely be useful functionality.

#pragma objective-c: can you have more than just 'mark'?

I am familiar with #pragma mark objective-c / xcode / ios development and that it is useful for finding sections of code.
However, I am wondering if there are other keywords other than 'mark'. Like, can you do #pragma somethingelse? Thanks in advance!
First, some examples:
You can control diagnostics:
http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas
And from the same link:
clang supports the Microsoft "#pragma pack" feature for controlling record layout. GCC also contains support for this feature, however where MSVC and GCC are incompatible clang follows the MSVC definition.
clang supports the Microsoft #pragma comment(lib, "foo.lib") feature for automatically linking against the specified library. Currently this feature only works with the Visual C++ linker.
clang supports the Microsoft #pragma comment(linker, "/flag:foo") feature for adding linker flags to COFF object files. The user is responsible for ensuring that the linker understands the flags.
The second and third from that list won't apply to your iOS code, though.
Wikipedia [link] says that clang supports #pragma once, too.
And finally, here's a link to the clang API documentation for the pragma handling code. You can browse from there to see everything else. In particular, TokenKinds.def describes all the accepted tokens, so presumably it's complete:
#pragma unused
#pragma GCC visibility [push/pop]
#pragma pack [value/show/push/pop/etc/etc/etc]
#pragma clang __debug parser_crash
#pragma clang __debug captured
#pragma ms_struct [on/off]
#pragma align [native/natural/mac68k/power/reset]
#pragma weak [identifier]
#pragma weak [identifier = identifier] // alias
#pragma redefine_extname [identifier identifier]
#pragma STDC FP_CONTRACT
#pragma OPENCL EXTENSION
#pragma omp [...]
#pragma detect_mismatch
#pragma comment
The parsing code, found in ParsePragma.cpp, seems to indicate that not all of them are implemented, even if the front-end accepts them, though.
Yes. It's often used for implementation defined directives, but there are a few which are defined in C.
6.10.6 Pragma directive Semantics 1
A preprocessing directive of the form # pragma pp-tokensopt new-line where the preprocessing token STDC does not immediately
follow pragma in the directive (prior to any macro replacement)
causes the implementation to behave in an implementation-defined
manner. The behavior might cause translation to fail or cause the
translator or the resulting program to behave in a non-conforming
manner. Any such pragma that is not recognized by the implementation
is ignored.
If the preprocessing token STDC does immediately follow pragma in the directive (prior to any macro replacement), then no macro
replacement is performed on the directive, and the directive shall
have one of the following forms whose meanings are described
elsewhere:
#pragma STDC FP_CONTRACT on-off-switch
#pragma STDC FENV_ACCESS on-off-switch
#pragma STDC CX_LIMITED_RANGE on-off-switch
`on-off-switch`: one of `ON OFF DEFAULT`
Carl Norum's answer covered examples of implementation defined directives well. For a complete list, you should refer to your compiler's documentation.

Resources