I have a header file containing an interface with properties and methods (let's call it E.h), and Xcode notifies me about syntax errors inside this header field, which make no sense because E.h doesn't contain any error.
These errors appear only under certain conditions:
E.h is already included in A.h, and there is no error.
When E.h is not included in B.m, there is no errors and it compiles fine, but if I include it in B.m, errors show up. (B.m doen't use any code from E.h)
Additional information: B.m includes B.h and then E.h .
I didn't find relevant to include source code because it represents thousands of lines and I won't ask you to analyze this.
I jus need some hints for what could be the cause and where to start searching.
Thanks in advance.
By using the "Show Preprocess" option in Xcode, I found that the property in E.h named #property (retain) NSString *MY_STRING; was replaced with #property (retain) NSString *#"My String". It appeared that there was a define MY_STRING #"My String" included in a different header file itself included in B.h, itself included in B.m before E.h .Hard to spot ! Lesson of the day : never write your variables in upper case.
In C++ this works, maybe will help you:
in file E.h
#ifndef __ECLASS__
#define __ECLASS__
<here original declarations from E.h>
#endif
Related
Summary:
Error I'm experiencing is as title states.
I'm encountering a Reference to '' is ambiguous error. I've been unable to determine what the problem, whether if my import structure is set up incorrectly and the headers are somehow included multiple times or whatnot.
Due to request and requirements, I'm currently trying to build a single view iOS application using Objective-C and C while importing a custom pure C SDK. This is my first time using C in an iOS application, let alone including a whole SDK, so I'm not 100% sure if the process I'm doing this is correct, but have been able to resolve errors as I've been compiling.
SDK files are being included via a prefix.h which is imported into the single viewcontroller's header. I also read somewhere to use .pch instead of .h, but I'm not able to figure out how to do so given the requirements of this project...
Errors:
Reference to 'E_EXTERNAL_DEVICE_TYPE__CARD_ENTRY_DEVICE' is ambiguous.
"In file included from .../ViewController.m"
-"In file included from .../ViewController.h"
"In file included from .../prefix.h"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_TYPE__CARD_ENTRY_DEVICE'"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_TYPE__CARD_ENTRY_DEVICE'"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_TYPE__CARD_ENTRY_DEVICE'"
Reference to 'E_EXTERNAL_DEVICE_CONNECT_TYPE__BLUETOOTH' is ambiguous.
"In file included from .../ViewController.m"
"In file included from .../ViewController.h"
"In file included from .../prefix.h"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_CONNECT_TYPE__BLUETOOTH'"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_CONNECT_TYPE__BLUETOOTH'"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_CONNECT_TYPE__BLUETOOTH'"
Reference to 'E_EXTERNAL_DEVICE_TYPE__PRINTER' is ambiguous.
"In file included from .../ViewController.m"
"In file included from .../ViewController.h"
"In file included from .../prefix.h"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_TYPE__PRINTER'"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_TYPE__PRINTER'"
"Candidate found by name lookup is'_E_EXTERNAL_DEVICE_TYPE__PRINTER'"
// Device.c
...
// this and other similiar lines of code that throws the error
if((deviceType == E_EXTERNAL_DEVICE_TYPE__CARD_ENTRY_DEVICE) && E_EXTERNAL_DEVICE_CONNECT_TYPE__BLUETOOTH) {
CODE x = E_EXTERNAL_DEVICE_TYPE__PRINTER;
}
Solutions attempted
The strange part is, at one point I was able to build and run parts of the project by interatively uncommenting lines and debugging lines of code as I went along starting with SDKInitialize. But for some unknown reason, I'm now getting this error even though I've commented the SDKInitialize() in ViewController.m such that it's just an empty ViewController doing nothing.
I've also tried reverting back an older git version where the project could build fine, but it's still encountering the same error, which possibly leads me to believe this may be related to the XCode IDE or some kind of configuration settings...
cleaned project
deleted everything inside '~/Library/Developer/Xcode/DerivedData/ModuleCache/'
clean once more
build project
Already checked
Reference to 'X' is ambiguous
Reference to 'CMTime' is ambiguous
Reference to enum is ambiguous objective-c
Xcode: "Reference to NSString is ambiguous"
Build Settings
I have tried setting setting always_search_user_paths = No;
Always Search User Paths = Yes;
Header Search Paths[$(PROJECT_DIR)/.../.../.../SDK/Common] = recursive;
Header Search Paths[$(PROJECT_DIR)/.../.../.../SDK/Core] = recursive;
Header Search Paths[$(PROJECT_DIR)/.../.../.../GenericAppRoot] = non-recursive;
... etc
FYI app.xcodeproj exists inside ___/GenericAppRoot/Devices/iOS
File Structure
Common.h
//located in $(PROJECT_DIR)/.../.../.../SDK/Common
//Common.h
#ifndef __DTISDK_COMMON_H__
#define __DTISDK_COMMON_H__
//--------
// SDK Includes
//--------
//...
//--------------
// External Device Types
//--------------
typedef enum _E_EXTERNAL_DEVICE_TYPE
{
E_EXTERNAL_DEVICE_TYPE__PRINTER = 1,
E_EXTERNAL_DEVICE_TYPE__CARD_ENTRY_DEVICE = 2,
E_EXTERNAL_DEVICE_TYPE__PIN_ENTRY_DEVICE = 3,
} E_EXTERNAL_DEVICE_TYPE;
//...
typedef enum _E_EXTERNAL_DEVICE_CONNECTION_TYPE
{
E_EXTERNAL_DEVICE_CONNECT_TYPE__AUDIO = 1,
E_EXTERNAL_DEVICE_CONNECT_TYPE__BLUETOOTH = 2,
} E_EXTERNAL_DEVICE_CONNECTION_TYPE;
//...
#endif //__DTISDK_COMMON_H__
prefix.h
#ifndef prefix_h
#define prefix_h
#include "File.h"
#include "File.c"
#include "System.h"
#include "System.c"
#include "Common.h"
... etc
ViewController.h
#import <UIKit/UIKit.h>
#import "prefix.h"
#interface ViewController: UIViewController
#end
ViewController.m
#import "ViewController.h"
#interface ViewController()
#end
#implementation ViewController
- (void) viewDidLoad {
[super viewDidLoad];
// initialization callback from one of the SDK classes
SDKInitialize();
}
#end
Any additional help or insights would be much appreciated
You are including *.c files from prefix.h which is wrong. Always include only header files (*.h).
When you are including the implementation (*.c) files, the contents of the file is inserted as is, therefore you get the same definition in multiple places, leading to name collisions.
We have a class WayPoint. But at some point, we decided to rename the class to Placemark. However, we don't really want to change the name of the class because it will result in a lot of modification of the existing code. Therefore, I added one line of typedef at the bottom of the header file and start using Placemark in any new code happily ever since.
#interface WayPoint : _WayPoint
#end
typedef WayPoint Placemark;
But there is still one thing that I don't understand. If I try to use the forward definition in some other header file. I can only used:
#class WayPoint;
If I use:
#class Placemark;
I will get the error message:
Redefinition of 'Placemark' as a different kind of symbol
Why?
Not sure why can't you use Xcode's refactoring features (Simple Rename does it fast and easy). But if you really want to do this you may use something better then typedef:
#compatibility_alias Placemark WayPoint
Because typedef Placemark is an alias and you are trying to use it as a class
symbol.
So error clearly indicates
Redefinition of 'Placemark' as a different kind of symbol
which means your class name and typedef alias are different symbol.
In an .h file I have the following line (outside of any #interface block):
static NSMutableDictionary *dictLookup;
In the corresponding .m file I try to initialize that static in the init method of the class:
dictLookup = [NSMutableDictionary dictionary];
dictLookup setValue:#"Hello?" forKey:#"Goodbye"];
However, when I insert breakpoints and do checks, dictLookup never becomes anything other than nil.
Also, I get a bizarre warning "Unused variable dictLookup" at compile time. Bizarre because if I delete the static declaration, then I get an "Undeclared identifier" compiler error at the lines in the init method.
I've since discovered there are better ways of doing what I want. But what was going on here? (1) Why can't I set dictLookup to anything?
Some sources seem to say that in C a static variable can only be used in the file in which it is declared. (2) If so, then why doesn't compiler fail with an error in the .m file? Given (1) that would seem to be the logical thing to design the compiler to do.
And (3) When I designed a new 'test' project from scratch, with a new .h/.m file combo like the one described, I WAS able to set dictLookup and insert keys. Why could accoutn for this difference?
When you put a declaration of a static variable in a .h file, it gets re-defined in every .m file from which the header is included. A brand-new variable will be created in each file, with the same name.
This is not an error in the .m file: the variable is local to that file, and invisible to the linker, so there are no "multiple definitions" error.
That's because your test project used a single .m file.
Some sources seem to say that in C a static variable can only be used in the file in which it is declared.
That is absolutely correct: a static variable is very much like a file-scoped global variable, it should be defined in the .m file. If you want to share a variable, it needs to be a global then. Declare it in the header with the extern keyword, like this
extern NSMutableDictionary *dictLookup;
and then define it in one of the .m files like this:
NSMutableDictionary *dictLookup;
I have something like this in my objective-C class
#interface PREFIX_MyClass {
...
#end
and I'd like to use the preprocessor to convert it to:
#interface AwesomeMyClass {
...
#end
so something like
#define PREFIX_ Awesome
doesn't work because it's a part of a word. Any other way? I know I can use something like this:
#define PrefixClass(NAME) Awesome##NAME
#interface PrefixClass(MyClass)
but I don't like this because it breaks code complete and reference following in dev tools (i.e.: Xcode in this case)
This isn't very elegant, but you could use the preprocessor to replace the entire class name instead of just part.
#define PREFIX_MyClass AwesomeMyClass
#interface PREFIX_MyClass
Of course, this becomes an issue if you use the prefix more than once and it changes. You could fix this using by using another calling another macro to add the prefix, so that only one macro contains the actual prefix.
#define ADD_PREFIX(name) Awesome##name
#define PREFIX_MyClass ADD_PREFIX(MyClass)
#interface PREFIX_MyClass
This still requires a macro for everything you want to prefix, but code completion will recognize the PREFIX_MyClass name.
This is not exactly what you're asking for, but it may be another route to accomplish your goal. Xcode allows you to define a class prefix for your project. Select your project in the file navigator, and in the file inspector (first "tab" of the right sidebar) you will have this:
Whatever text you put into the "Class Prefix" field will be prepended to the names of any classes you create in that project.
I'm learning objective-C and Cocoa. In the Apple tutorial I'm working through there's a side note that says:
IBOutlet is a null-defined macro, which the C preprocessor removes at compile time.
I'm curious - what's a null-defined macro?
#define IBOutlet
Whenever IBOutlet is used in program text, it will be replaced with nothing at all.
FYI, in this particular case, the reason the IBOutlet even exists is simply so that Interface Builder can parse the source file and glean bits of understanding from it. It's a clue (well, a bit stronger than a clue) that the variable preceded by IBOutlet should show up as an Outlet in Interface Builder when designing your UIs.
A null-defined macro is a macro which will be replaced by nothing (will be removed) by the preprocessor. It's role is to give a hint about something in code, such as:
#define IN
#define OUT
#define INOUT
int myFunction(IN char *name, INOUT char *address, OUT char *phone);
This declaration suggests that name is a input variable for the function, address is both input and output, phone is an output variable.
Also - if you're unsure how anything is defined - command double-click it and Xcode will open the definition in the original source file.
Oh and while I'm at it. Option double click will (attempt to) open up the documentation for the double clicked symbol.