Error: 'class name' redeclared as different kind of symbol? - iphone

I was facing the same error as asked in this question
I overcome with this error by solution of declaring class ahead of time in my .h file with the class parameter
I am having FFTBufferManager.h and FFTBufferManager.cpp file and using it in HomeView.h and HomeView.mm file
class FFTBufferManager,CAStreamBasicDescription,DCRejectionFilter;
But now I am having error as
#include "FFTBufferManager.h"
#include "aurio_helper.h"
#include "CAStreamBasicDescription.h"
class CAStreamBasicDescription,FFTBufferManager; //here it shows this error
EXpected Unqualified-id befor ',' token
#interface HomeView
{
FFTBufferManager* fftBufferManager;
//it shows erros
EXpected Unqualified-id befor ',' token
ISO c++ forbids declaration of FFTBufferManager with no type
}
#property FFTBufferManager* fftBufferManager;
//shows error
'FFTBufferManager' is not a type

I'm gathering you're using both C++ and Objective-C.
I'd suggest renaming all your .cpp and .m files in which Objective-C and C++ code are meeting to use the extension .mm - this tells the compiler to use "Objective-C++" rules, and will stop a lot of compiler troubles.
Also, it seems CAStreamBasicDescritpion is a C++ class - you'll have to forward-declare it with class CAStreamBasicDescritpion;, not #class CAStreamBasicDescritpion; (note, no "at" sign) - the second form is only for forward-declaring Objective-C classes. This I suspect is the root cause of the particular error you have observed.
EDIT in response to comment: I'm not sure about your first new issue - that should work fine so long as both FFTBufferManager and CAStreamBasicDescription are C++ classes. As to your second one, depending on where exactly that line of code is (CAStreamBasicDescription thruFormat;) you may need to include the header rather than just the forward-declare: you're declaring an instance of CAStreamBasicDescription here, and the compiler needs to know its structure to do so.

You can't declare more than one class at a time.
Change your declarations to
class CAStreamBasicDescription;
class FFTBufferManager;
The compiler is looking for an unqualified-id because it believes that you're declaring a variable of type CAStreamBasicDescription, so it expects a variable name where you gave it a comma.

Looks like you are trying to create a class that already exists in one of the Cocoa frameworks.

Related

Redefinition of 'ClassName' as different kind of symbol in generated header

I created a Swift enum as an Int (so it will work with Objective-c).
When I build the project, everything is fine. However, as soon as I try to import the class in a .h file (using a forward declaration #ClassName), the generated header file errors out with Redefinition of 'ClassName' as a different kind of symbol
Looking in the generated .h file I can see it generated the new type like so:
typedef SWIFT_ENUM(NSInteger, ClassName, closed) {
type1 = 1,
type2 = 2,
};
It underlines the ClassName saying it's been re-declared. However, it exists nowhere else in the header file (doing a search and it comes up only once) and it's only declared once in a swift file.
Any suggestions on what is going on?
Enums are not classes in Objective-C, so you need to use typedef instead of forward declaration in your .h file:
typedef NS_ENUM(NSInteger, ClassName);
and then in .m file, you need to import Module-Swift.h file.

C++ Is "class Name*" a class pointer?

I was watching an unreal tutorial and encountered this line of code:
class UStaticMeshComponent* Pickup;
It is a forwards declaration.
I have been studying c++ for a while and have not encountered anything like this before. I know about pointers and references, but I never seen this format: class Name*. Are we creating a class pointer to another class? I tried searching for class names followed by a *, but the only result that appeared were about data types and pointers.
public:
APickUp ();
virtual void BeginPlay () override;
virtual void tick ( float DeltaSeconds );
private:
class UStaticMeshComponent* Pickup;
class UStaticMeshComponent* Pickup;
This declares the type class UStaticMeshComponent and also declares the variable Pickup of type pointer to UStaticMeshComponent. So the above code is more or less equivalent with:
class UStaticMeshComponent;
UStaticMeshComponent* Pickup;
Because at this point you don't have the definition of UStaticMeshComponent (just the declaration), UStaticMeshComponent is considered an incomplete type. There are a few things you can do with an incomplete type. One of them is declare pointers to them.
When you are only using a pointer to a type, the type is not required to be complete, so this works fine even if UStaticMeshComponent has not been defined. That means when this header is included in one of your cpp files, it should compile a bit faster than if Pickup.h were to include the header where UStaticMeshComponent is defined.
This speed up could be substantial depending on how big that header is, and how many times the include is avoided during compilation.
The big confusion here is the difference between:
class UStaticMeshComponent* Pickup;
and
class UStaticMeshComponent *Pickup;
and even this:
class UStaticMeshComponent * Pickup;
, as in the example http://www.cplusplus.com/doc/tutorial/classes/#pointers_to_classes .
The difference is - bad practice. All supposed to mean the same thing but only the second example is correct, yet all of them work.
At least according to this:
https://users.ece.cmu.edu/~eno/coding/CppCodingStandard.html
place the * close to variable name not pointer type
I am a novice, I might be wrong. Please correct me if i am wrong.

iPhone+Difference Between writing #classname & #import"classname.h" in Xcode [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
#class vs. #import
I am Really confused with this,Whats the difference between writing #classname & #import"classname.h" .When Do we go for #classname?
You can find a good answer here and in the Objective-C Programming Language documentation on ADC
#classname is a forward declaration. Nothing gets imported, it just informes the compiler, that the class will exist on runtime.
#import will actually import the other class -> you can imagine it as a copy it into the file. so the imported classes will get compiled before the one, that it is written in.
The #classname just let's the compiler know that the class exists however you'll still need to import the corresponding .h. You can use the #classname in the .h and then import the class in the .m and this will allow you to avoid circular references. You can read more about it here Apple Docs
#className directive is introduced to overcome cyclic reference of classes, it is also known as Forward Declaration
#class will just inform the compiler that there is a class named "#className yourClass" no need to worry about that class and in runtime it just refer that class and executes.
#import "className" will keep a copy of that particular class.
#classname just tells the compiler that the class classname exists.
#import really imports the header file so that the compiler not only knows that it exists, but also how it looks. (like ivars, methods etc...)

Why is my 'kMyConstant' macro redefined?

In my app delegate class I define a constant like so:
#define kSomeConstant #"My_Constant_Value"
I then want to make use of this constant in another viewController so I defined it again exactly as above. I now get the message:
'kSomeConstant' macro redefined
Why is this the case? Is there some other way I can access the constant?
Simply redefining the constant (ie : same constant name). Choose another name, or define it just one time in a header file to access the constant value every where you import that header.
It's likely been defined twice among the sources which are visible to the compiler. the compiler may tell you where the previous definition is if you look into the message in more detail.
To avoid this problem entirely, declare your NSString constants like this:
file.h - declaration:
extern NSString* const kSomeConstant;
file.m/mm - definition:
NSString* const kSomeConstant = #"My_Constant_Value";
Then when you need to use the constant, just #include "file.h".
The compiler has encountered two definitions of the macro. Probably you defined it in a header file and then defined it again in a .m file.
If you can't figure out where the two definitions come from, try preprocessing the file with the error (in Xcode 4.2 this is under generate output in the product menu). You can then do a search for kSomeConstant and that should tell you where it comes from.

Understanding Objective-C scope issue

Following is a snippet from a View Controller's implementation:
- (void)myOtherAwesomeMethod
{
[self myAwesomeMethod]; // Compile ERROR here: Receiver type for instance message does not declare a method with selector
}
- (void)myAwesomeMethod
{
NSLog(#"%#", #"Calling my awesome method...");
}
- (void)viewDidLoad
{
[self myAwesomeMethod];
[self myOtherAwesomeMethod];
}
I do not have myAwesomeMethod method declared in my header file, but why is it that I can call myAwesomeMethod in viewDidLoad, but not in myOtherAwesomeMethod?
I know the solution to this error is to declare the method in my header file, but I'd like to understand why this is happening.
In C, the rule is: you got to declare it before you use it.
Files are compiled from the top down. So here's what is happening in your code:
The compiler reads the #interface declaration for your class. Since you say neither method is declared in the header file, neither are in the symbol table yet.
Your symbol table contains: nothing yet
The compiler reads the method definition for myAwesomeMethod. You haven't declared it yet, so it gets added to the symbol table. The body of the method contains a call to NSLog, which was declared long ago in a header provided to you by Apple.
Your symbol table contains: myAwesomeMethod
The compiler reads the method definition for viewDidLoad; it was actually declared in a superclass's header file. The body of the method contains a call to myAwesomeMethod, which was found! It also contains a call to myOtherAwesomeMethod. Never heard of it!
Now, this isn't an error, because it can still generate the code to make the call. It can infer argument types by how you use it (in this case, no arguments). It can't be sure of the return type, though (just because you don't use the return value doesn't mean there wasn't one). So it proceeds on the assumption that the call returns id and generates a warning.
Your symbol table contains: myAwesomeMethod
Finally, the compiler reads the method definition for myOtherAwesomeMethod. It gets added to the symbol table. It compiles the body, which contains a call to myAwesomeMethod, which is in the table. All's well that ends well.
At the end of the file, your symbol table contains: myAwesomeMethod, myOtherAwesomeMethod
If you're coming from a language like Java, this may seem silly, but that's because Java works differently than C. In Java, source code is compiled and linked in one step; you can't compile a class that refers to another class without having either the source code or class files available. That can be a hassle, but on the other hand, you never need about declarations apart from definitions.
In C, compiling and linking are different steps. The compiler just generates object code that refers to symbols that may be defined elsewhere; it uses declarations to make sure it generates the right code. The linker is responsible for matching up all those symbols with definitions in other libraries, static or dynamic.
In Objective-C, the linker doesn't actually know/care about Objective-C messages, because there is no way of knowing at compile-time/link-time whether an object can respond to a message. So it passes the buck to the runtime, which throws an exception if you get that far without a method definition.
I admit I'm not sure why it works in viewDidLoad.
Notice that the error says "did not DECLARE" a method. That's a hint that it's looking for a declaration (typically in a header)..ie a function prototype.
However, there's nothing that says a declaration has to be in a header. YOu can put it at the top of the implementation file if you're not going to call that method from outside the file.