I have added some objective C files and c++ files to an existing iOS project. When I import a .h file of a .mm file into a .h file with a corresponding .m file I get all kinds of errors.
When I change the .m file of the .h file importing the new code to .mm I then get the same previous errors but with new errors regarding the new .mm file.
Im not really sure how to fix this.
I am using ARC if this has any effect.
It complains about namespace (unknown type), also Unknown name issues with an imported .mm file, expected expression error on a statement containing :: in a .h file of a .mm file. What I dont get is that these files work correctly in the project I copied them over from. I only took the source from the project. And have added header search paths to the directory. I also selected create references to the added directories option.
For some reason the files arent in the compile source section, and when I try to add them, the file selector tree doesnt contain these source files I added. The added directory is also blue instead of yellow, but empty.
As you know, C++ code can only be used from .mm files. When the compiler complains about namespace being an unknown type, it typically means that the Objective C compiler is being used when the Objective C++ compiler should be used. More simply: you have a .m file that needs to be a .mm.
Speaking generally, there are two options you can pursue. Every time an Objective C file complains, change it to a .mm. This is a slippery slope, and generally results in your entire project cascading into a giant ball of Objective C++. The other option is to quarantine the C++, so that only a bare minimum of your Objective C files need the .mm extension.
Obviously, the latter is the better choice. The likely cause of the confusion is #importing a header file that contains C++ code from elsewhere in your app that doesn't actually require C++. If the C++ is an implementation detail of an Objective C class, you can try to keep the C++ out of the class' header file by leveraging Class Extensions. Otherwise, you can create an Objective C class whose only purpose is to wrap the C++ in its own implementation, while exposing a clean header file for other classes to consume.
Basically, If you can keep your headers clean, then you won't have to worry about accidentally indirectly #importing some C++ into an unsuspecting compilation unit.
Related
I've recently started learning cpp from basics and was very much confused with the folowing:
Lets say I have a header( test.h which contains only declarations) with some content and some source file (source.cpp) and program produced some result.
If I have copied the same content of that header file to a .cpp file (testcpp.cpp) and included this in source.cpp
In this case, I did not understood what difference it makes?
(I'll not include this testcpp.cpp in make file)
I have seen some threads similar to this but couldn't get a clear idea!!!
I learnt the usage of header and cpp files and have used it correctly in projects till now, Please answer specific to this scenario (I know doing this way adds confusion but just want to know). Will there be any difference doing so or it's just a common practice everyone follows ?
what difference it makes?
The extension of a header file has no effect on anything. You could have just as well named the file test.mpg, .test or just test (changing the include directive obviously), and it would have worked just as well. The extension is for the benefit of the programmer, not the toolchain.
However, it is a bad idea to name it anything other than .h, .hpp or whatever is your convention. If you name it .mpg, people will think that it is a video, and not realising that it is a header file, try to play it in a media player. If you name it .cpp, people will think that it is a source file and may attempt to compile it or maybe add definitions into it.
Including a file with the preprocessor is technically just copying contents of one file into another. Nothing more and nothing less. Everything else about them is just convention.
In makefile, when specifying source file, Can I give my source files with any extension(.fsfs, .xxx) rather than .cpp extension
Technically yes, however compilers usually use the source file extension to detect the language which they will fail to do in this case, so you would have to specify it explicitly.
It changes nothing. It's just a convention whether you use a *.h or *.cpp or *.asdasd suffix, as long as it doesn't get compiled by itself.
Some projects use the .hxx extension for header files and .cc for source file.
Please, for the good of fellow programmers you'll work with, stick to common conventions and don't put header code in .cpp files.
#include just does a copy-n-paste of the file you include into the current file. What the file is named doesn't matter one bit - you can name it "foo.exe" if you like; as long as it contains valid source-code in the context where it is included all is well (but please don't use unconventional names, you'll just confuse people).
I have a question about using C++ header files in Objective-C++ modules in Xcode. Specifically, why can I #include them in source files but not header files?
Here is a specific example.
I'm using Xcode 7.2.1 and have two projects. The first is a C++ framework I package into "myFramework.framework". It exposes "myFramework.h", which in turn pulls in "myLib.h". At the top of "myLib.h" is an "#include <string>".
The second project is an Objective-C iOS app which consumes the above framework. In this project, "myViewController.mm" (Objective-C++ source) has "#import "myFramework/myFramework.h" at the top and makes reference to things defined in that header file.
At this point all is well and good. It builds and runs with no issues.
When I move the "#import myFramework/myFramework.h" line to "myViewController.h", the compile fails because it cannot locate the "" header dependency.
It doesn't matter if I change the file type for "myViewController.h" to Objective-C++ header from plain old "C Header". Either way, Xcode's header search paths don't look for standard C++ headers.
So my main question is why does it behave this way? Why is a #include/#import treated differently just because it's in a header file?
My second question is if there's some way to make Xcode treat the #include/#import the same when it's in the header file instead of the source file?
Thanks much!
Are you sure that you get the error while compiling the myViewController.mm file?
Check if myViewController.h is imported into some other, non ObjC++ file (and that that one is the file that fails to compile).
I suspect the issue with including C++ headers inside other headers is that an Objective-C source file gets to see the C++ header file, which upsets it.
If you have mixed C++/Objective-C++/Objective-C then you are probably better off only exposing a pure Objective-C interface to other modules in the project and include any C++ header files in the Objective-C++ source files only.
Alternatively make everything Objective-C++ and then you don't need to worry about it at all.
Hopefully this answers your second question as well.
I have been thinking this problem for a while but still no idea about it, if my project is mainly cpp file, should a c file name as .c, or should be named as .cpp to consistent with other .cpp file?
I just list some advantage and disadvantage (in my current knowledge) of using .c (I don't know if the following idea is correct):
advantage of .c:
fast to know it does not contain c++ content (e.g.:class,std::string)
easy to separate from .cpp file by searching name
disadvantage of .c:
not consistent with other files (because other files mostly .cpp)
may need to rename it as .cpp if I want to change the function as using oop or want to add some oop features into it
some scripts or files may need to add *.c as file input if the original version only handles *.cpp, (e.g.: need to add *.c in Android.mk in android jni)
Also I don't know if compiler handles .c and .cpp in different way,also don't know if it affects other behaviour (e.g.:performance,platform or compiler specific issues...), is anyone have idea about it?
Depends what you mean by "C" code.
Are you going to compile it with a C compiler?
Call it file.c
Or do you just mean "C-like" C++ code? C++ code that, at time of writing, happens to also be valid C?
Call it file.cpp
Rule of thumb - name it according to which compiler you intend to use for it. This keeps your makefiles nice and simple.
So if your "C code" is C++ code that could be compiled as valid C but that's not what you are doing, then name it *.cpp and let your makefile invoke the C++ compiler on it.
If your code is actual C, to be compiled with a C compiler, then name it *.c - and remember the (appropriately-#ifdefed) extern "C" in the header file so that C++ built against it can link successfully.
C++ fully supports c code. So the compiler would be just fine with c code in a .cpp file.
And like Quentin mentioned above. If your c code is never used in a c only project I would leave it in an cpp file.
I've made a struct which does cached file manipulation for my application. I built and tested to in a separate project before putting it into my current one.
Ever since I've moved it over, Xcode refuses to build it. Except when I don't include the file from any Objective-C based header file.
I get one error when I try to include iostream:
And more when I comment it out:
Its file extension is .mm, however I have tried it with .cpp and .hpp, but all of them refuse to build unless I don't #include it from the Objective-C header file.
I've also tried #import from iostream and the file itself in the Objective-C header file.
Any clues as to why this is happening?
As a matter of principle, you cannot include a C++ header file from an objective-C source file.
After all, #including (or #importing) a file only means that the preprocessor replaces the #include directive by the contents of the #included file, before passing the result on to the "actual" compiler. The file extension of the header file is a matter of convention, only, it has no actual meaning.
The error messages your are seeing are clearly the result of the file being compiled as [Objective-]C rather than [Objective-]C++.
Solution: All the source files that include your C++ header file have to be either C++ (.cpp or .cc or a few other extensions) or Objective-C++ (.mm). All source files that include a header file that includes your C++ header file, also have to be C++ or Objective-C++.
EDIT: I just saw that you are defining non-inline, non-template functions in your C++ file that you want to include. This is an unrelated problem, but it will lead to "multiple definition" errors sooner or later. Those function definitions belong in a .cpp, which shouldn't get #included anywhere, only the struct/class definition belongs in a header.
Take a look here and here. You need to tell the compiler to include libstdc++. When mixing Objective-C and C++ all you're files need to have the ".mm" extension, as stated in the second link.
I suspect the error is occurring when you compile a .m or .c file that includes the same header.
I have a few classes I wrote to deal with numbers having units transparently as if they were just ints or floats. In a nutshell:
SI_Term speed(4, "mph");
SI_Term distance(10000, "feet");
SI_Term time = distance / speed;
std::cout<<time.string();
and all the major operators are overloaded to work this way. Took a quite a bit of work so I would like to use the C++ classes in my ObjC iPhone app. I tried adding them with .h and .mm extensions to my xcode project, but it doesn't seem to be treating them as C++ files. (Won't find any of the STL headers, syntax errors anywhere I declare a class or anything).
New Info:
Tried .mm and .h extensions, errors:
in a .h file:
namespace DA and just about everything else involving c++ code (about 40 errors all this message) gives me expected '=', ',', ';', 'asm' or '__attribute__' before ':' token
I also get *: No such file or directory for all instances of #include <*> throughout the c++ files.
I'm sure its some kind of simple fix but .mm and .h wasn't enough.
Update:
Found that copying and pasting source code into new files seems to work. The mm file (or the cpp file) compiles. The h file doesn't work though, it throws the above mentioned error at any occurrence of c++ specific code.
Thanks!
You are probably including (or importing) your h file in one of your .m files. Those need to be renamed to .mm too.
In the end you'll probably name all .m fikes to .mm. And by the way, the cpp files, can simply remain cpp. No reason to rename them.
Not knowing exactly what the errors you're getting are, rather than adding your files with a .hpp and .cpp extension to your project, I would change the extension of the header files to just .h, and the extension to your .cpp files to either .mm or .M so that Xcode recognizes them as Objective-C++ files, and compiles them appropriately.