Fix "Lexical or Preprocessor Issue - Extension used" warning in Xcode? - ios

I've inherited a new project, which has several retain cycle warnings caused by implicitly retaining self within various blocks.
In attempting to fix these, I've written
__weak typeof(self) weakSelf = self;
to create a weak reference for use within the block.
However, Xcode v. 5.1.1 is giving the cryptic warning
Lexical or Preprocessor Issue
Extension used
I'm at a loss here-- what does this mean and how can I get rid of it?

You get this warning for the use of typeof if "Pedantic Warnings" are enabled in the build settings.
From the "Quick Help" for this setting:
Description Issue all the warnings demanded by strict ISO C and ISO
C++; reject all programs that use forbidden extensions, and some other
programs that do not follow ISO C and ISO C++. For ISO C, follows the
version of the ISO C standard specified by any -std option used.
[GCC_WARN_PEDANTIC, -pedantic]
I am not an expert in (ISO) C standards, but according to
https://gcc.gnu.org/onlinedocs/gcc/Typeof.html:
If you are writing a header file that must work when included in ISO C
programs, write __typeof__ instead of typeof. See Alternate Keywords.
and http://clang.llvm.org/docs/UsersManual.html:
The parser recognizes “asm” and “typeof” as keywords in gnu* modes;
the variants “__asm__” and “__typeof__” are recognized in all modes.
you can use __typeof__ instead
if you don't want to disable the warning:
__weak __typeof__(self) weakSelf = self;

Related

LLDB How to use a file-defined macro in OC

Ive tried multiple variations of this, but none of them seem to work. Any ideas?
in ViewController.m
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 300, 300)];
view1.backgroundColor = [UIColor redColor];
[self.view addSubview:view1];
Another file UIView+Frame.h
I defined a color macro
#define RGBACOLOR(r,g,b,a) [UIColor colorWithRGB:r Green:g Blue:b Alpha:a]
Actual operation
When the program executes [self.view addSubview: view1];I am going to use LLDB to use the defined macros to modify the color, but it prompts an error and I do n’t know how to modify it.
The wrong result is as follows
(lldb) e view1.backgroundColor = (UIColor *)RGBACOLOR(0,0,0,1)
error: use of undeclared identifier 'RGBACOLOR'
(lldb)
Macros are not traditionally well supported by debug info. The DWARF standard (which is the most common one on macOS & other Unixen) has a way to store the information, but it is so verbose very few toolchains support it. So there's no natural way for the debugger to know about defines.
If you have a small number of fairly independent macros you want to use in debug expressions, you can put them in a .h file, and set that file as lldb's "expression prefix". This will get included into the source of every expression you run subsequently. Do this by:
(lldb) settings set target.expr-prefix ~/my-common-defines.h
You can't get too ambitious here (e.g. #include <unistd.h> won't work). The problem is that most system header files are conditioned by a set of other #defines. lldb doesn't know what their values are, so at some point preprocessing the expr-prefix will fail.
Alternatively, clang also has a concept called "modules" which is an attempt to make the collection of headers from some package more shareable for repeated compilation. It actually captures some of the info that would cause the expr-prefix parsing to fail. So if the macro you want to access is in a set of headers that are built into a Clang module, then you can import the module into lldb's expression context, and that will make the defines from the modules available as well. So for instance:
(lldb) expr -l objc -- #import Foundation
will make all the Foundation macro definitions available.
Similarly, if your headers are modular (this page goes into depth on what this means:
https://clang.llvm.org/docs/Modules.html
) then you can import the module you've created, and its defines will be available to the expression parser.

Cannot resolve enum values by name in Xcode debugger

With an enum typedef'd in a global header file used throughout my project, I am unable to refer to the individual enum values by name while using lldb in Xcode.
For example, if I am stopped at a breakpoint anywhere the enum type is available, and I try to evaluate something at the lldb prompt in Xcode (e.g. (lldb) p (int)EnumConstant), lldb complains:
error: use of undeclared identifier 'EnumConstant'
Furthermore, if I try to set a conditional breakpoint using an enum constant in the condition (e.g. right-click breakpoint in Xcode > Edit Breakpoint... > Condition: EnumConstant == someLocalVar), then Xcode complains every time it tries to evaluate that condition at that breakpoint:
Stopped due to an error evaluating condition of breakpoint 1.1: "EnumConstant == someLocalVar"
Couldn't parse conditional expression:
error: use of undeclared identifier 'EnumConstant'
Xcode's code completion popover even resolves a suggestion for the enum constant when I begin typing the name in the "Edit Breakpoint..." window, so Xcode itself doesn't have a problem resolving it.
Is there an option I can set in lldb or Xcode so that lldb maintains the enum identifiers after compilation? I'm assuming the enum constants get translated to their ordinal value during compilation, causing the executable to discard the identifiers, but thats just my naive speculation.
When I use the equivalent code in a simple GNU C program in Linux or Cygwin (minus the class definitions obviously), but using gcc/gdb instead of Xcode/lldb, I don't have these problems. It is able to resolve the enum values no problem.
I've created a tiny Xcode iPhone project to demonstrate what I mean. Using any of the enum_t constants below within the ViewController.m context (the for-loop is a good place to demo) will produce the same results.
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
typedef enum
{
eZero, eOne, eTwo, eCOUNT
}
enum_t;
extern NSString const * const ENUM_STR[];
#end
ViewController.m:
#import "ViewController.h"
#implementation ViewController
NSString const * const ENUM_STR[eCOUNT] = { #"eZero", #"eOne", #"eTwo" };
- (void)viewDidLoad
{
[super viewDidLoad];
for (enum_t value = eZero; value < eCOUNT; ++value)
{
NSLog(#"%-8# = %d", ENUM_STR[value], value);
}
}
#end
This is a bug (fairly longstanding) in how the name->Debug Information lookup-accelerator tables for enums are built. While enum types are listed, enum values are not. That was surely done to save output debug info size - debug information gets quite big pretty quickly, and so there's a constant tension between the cost of adding more info and the utility of that more info. So far this one hasn't risen to the level of inclusion.
Anyway, doing a search through "all debug information for anything with a name that matches 'eZero'" is prohibitively slow even for decent sized projects, and gets really bad for large ones. So lldb always uses these name->Debug Info tables for its first level access.
Because the accelerator tables do contain the enum type by name (and more important for you typedefs by name as well), the workaround is to do:
(lldb) expr enum_t::eZero
(int) $0 = 0
Of course, if you have truly anonymous enums, then you are pretty much out of luck till this info gets added to the accelerator tables.
BTW, the Xcode symbol completion in the Debugger Console window is done using the Xcode SourceKit indexer, not lldb. So the completions offered from Xcode are not a reflection of lldb's knowledge of the program.
BBTW, gdb doesn't use compiler-made accelerator tables (these were an Apple extension up till the new DWARF 5 standard) but manually builds an index by scanning the debug info. That allows them to index whatever seems best to the debugger. OTOH, it makes debugger startup quite a bit slower for big projects.

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.

Getting "Expected a type" error in XCode

I'm getting this error:
/Class/GData/OAuth/GDataOAuthViewControllerTouch.m:116:22: Expected a type
That line is:
authentication:(GDataOAuthAuthentication *)auth
Inside of this block of code:
- (id)initWithScope:(NSString *)scope
language:(NSString *)language
requestTokenURL:(NSURL *)requestURL
authorizeTokenURL:(NSURL *)authorizeURL
accessTokenURL:(NSURL *)accessURL
authentication:(GDataOAuthAuthentication *)auth
appServiceName:(NSString *)keychainAppServiceName
delegate:(id)delegate
finishedSelector:(SEL)finishedSelector {
NSString *nibName = [[self class] authNibName];
I'm a newb XCode developer. So far I've created and compiled a calculator app based from an online class but that's it.
Is this a library that is not being included?
Background: The previous developer abandoned the project and the owner sent the project code to me. I'm trying to replace the existing graphics with new graphics and recompile it with support for iOS 6, which I thought I should be able to do without any coding, but have run into this error and many others when I opened the project. I have the latest XCode.
The :22 (and the position of the caret within the editor) tell you exactly where on the line the error is. In this case it's telling you that where it sees GDataOAuthAuthentication it was expecting a type. So, implicitly, it doesn't recognise that GDataOAuthAuthentication is a type.
Objective-C still sits upon compilation units ala C — each .m file is compiled in isolation then the lot are linked together. You use #import (or #include if you want; #import just guarantees the same file won't be included twice) to give each individual file visible sight of any external definitions it needs.
So, that's a long-winded way of reaching the same conclusion as Rick did five minutes ago: you've probably omitted a necessary #import.
A few things to look for:
Did you #import the file where the GDataOAuthAuthentication type is defined? (e.g. #import "GDataOAuthAuthentication.h")
Is there a variable named GDataOAuthAuthentication which is causing the compiler to think GDataOAuthAuthentication is a variable not a type?

How to access C function from another C function in iOS

I'm trying to assign a function to the AURenderCallback inputProc
int setupRemoteIO(audio unit etc){
inProc.inputProc = playerCallback
}
but it says that playerCallback is not declared in this scope although playerCallback is present in the same file and class as setupRemoteIO.
The player callback is like this
static OSStatus playerCallback(void *inRefCon etc)
What could be the problem?
In C, you need to declare a function before its first use, i.e. higher up in the file than the point where you try to use the function. That's why include files are usually clustered at the top of a file; all of the symbols declared in the headers will be available throughout the code in the including file.
In this case, that means the declaration of your callback:
static OSStatus playerCallback(void *inRefCon etc);
must appear before your setupRemoteIO() function so that the compiler knows the function exists when you come to use it.
As you're on iOS, I'll also make the point that in recent compilers this restriction doesn't apply to Objective-C methods. It used to: you could only use method selectors that had already been seen. But in newer versions of Clang an Objective-C method can make use of a selector declared later in the same file without error.

Resources