I have included a header file for a library in my ARC-enabled Objective-C project.
I know the library is not compiled with ARC enabled, but the problem is the header file of the library, specifically these lines:
template <typename Type_>
static inline Type_ &MSHookIvar(id self, const char *name) {
Ivar ivar(class_getInstanceVariable(object_getClass(self), name));
void *pointer(ivar == NULL ? NULL : reinterpret_cast<char *>(self) + ivar_getOffset(ivar));
return *reinterpret_cast<Type_ *>(pointer);
}
I get this error:
Cast of an Objective-C pointer to 'char *' is disallowed with ARC
Is it possible to fix this error?
The whole header file can be found here: http://puu.sh/sTrH
You need to change the initialization of pointer to this:
void *pointer(ivar == NULL ? NULL : reinterpret_cast<char *>((__bridge void *)self) + ivar_getOffset(ivar));
Go to the target of your project and select the Build Phases tab. Open the Compile Sources section and find that header file. Add the compiler flag "-fno-objc-arc" minus the quotes. This will cause that file to be compiled regularly and should fix your issue assuming the code works in a non arc environment.
Related
I'm trying to compile a project that has the following header:locale.h;
locale.h:
class LOG4CXX_EXPORT Locale
{
public:
...
protected:
Locale(const Locale&);
Locale& operator=(const Locale&);
const LogString language; <-- error
const LogString country; <-- error
const LogString variant; <-- error
}; // class Locale
Could anyone give me some suggestions ?
I'm getting this error. I am not sure
what is the problem.
/LOGGER/include/log4cxx/helpers/locale.h:42:41: error: field ‘language’ has incomplete type
const LogString language;
^
/LOGGER/include/log4cxx/helpers/locale.h:43:41: error: field ‘country’ has incomplete type
const LogString country;
^
/LOGGER/include/log4cxx/helpers/locale.h:44:41: error: field ‘variant’ has incomplete type
Consider the following code:
class MyClass;
int method1(const MyClass& param);
MyClass& method2();
const MyClass instance; // <- error here
The declaration of MyClass is a forward declaration. All the compiler know is that the class exists (it doesn't know its members, size...), that's why it is called an incomplete type. You can use references or pointers of that class, but that's it. See more info here When can I use a forward declaration?
So it seems that in your code, you only have a forward declaration of LogString type, and not a full declaration. Check your include files and include order so you get the full declaration of this class.
You are using std::basic_string, but there is no include for the appropriate header file:
#include <string>
What AnT wrote in a comment is the solution to the problem:
<clocale> is including your <locale.h> instead of the system one it ought to do; your locale is trying to include <string>, which again includes <clocale>.
So in the end, you get a circular include as I described in your other question https://stackoverflow.com/questions/32379927/header-file-does-not-compile-locale-h, just the chain being longer...
You need to break this inclusion circle. You can do this by removing the directory the file resides in from the inclusion directories you pass to gcc (I suppose this is -I"/LOGGER/include/log4cxx/helpers"). Instead, you can give a path to the parent directory (-I"/LOGGER/include/"). Instead of #include <locale.h> you would have to use #include <log4cxx/helpers/locale.h>.
Actually, I recommend keeping "/LOGGER/include" as the only directory you give gcc and have all other files you need included via the corresponding subpath - provided the rest of the log4cxx files allow that (which I would assume).
Apart from that, the only other way to solve the problem is indeed renaming your 'locale.h' file to something else (apart from changine the include path division, such as -I"/LOGGER/include/log4cxx" and #include <helpers/locale.h>; the one I chose, however, is the most natural one IMO).
Hej guys,
Need some help with this lint warning:
Symbol 'isCapable(std::basic_string) const' redeclared (signed/unsigned,precision) conflicts with....
There are two files:
header and source file
in header i have next declaration(which is part of class):
bool isCapable(std::string Name) const;
in source file:
bool Factory::isCapable(std::string Name) const
{
//some code
}
I tried to include string in source file too but no use. It still show this lint error.
Any ideas guys why is those lines are conflicted?
Sorry for stupid question. Actually conflict was because header was C header(with .h) while source file was C++ file(.cc) For just C we had defined bool as int since C doesnt have bool type. And well C++ has bool type...
I'm facing an interesting problem: I had an MFC application project in Visual C++ 6.0. Since there are many changes either in MFC or in C++ standard, I wanted to port my application to Visual Studio 2010. It was fine, but I am facing a warning now, which I can't handle.
The header file has the following class definition:
template <class T>
class foo : public CObject
{
// ...
// other stuff
// ...
private:
CTypedPtrMap<CMapWordToPtr, const long, T*> oElementMap;
void some_stuff();
}
In the source file there is:
template <class T>
void foo::some_stuff()
{
// ...
// other stuff
// ...
int nIndex = 0;
// ...
// other stuff
// ...
oElementMap.RemoveKey(nIndex);
}
When I try to compile this, I get the following warnings:
Warning 1 warning C4244: 'argument' : conversion from 'const long' to
'WORD', possible loss of data c:\programme\microsoft visual studio
10.0\vc\atlmfc\include\afxtempl.h 2066
It comes definetly from the above mentioned "RemoveKey" line: if I just simply comment out that line, I won't get this warning.
I know, the main problem is, that CTypedPtrMap object uses const long as key type, but CMapWordToPtr would have WORD (unsigned short) instead of it. But the fact is: I need const long as key type, since I am processing regulary about 1 million data entries in this map, so with unsigned short the class would not be capable to do it's job furthermore.
I tried to nest either the "RemoveKey" line or the include of stdafx.h into the following expressions, but neither worked:
#pragma warning (disable: 4244)
// expression
#pragma warning (default: 4244)
Please share me any ideas about this issue, how could I resolve this warning WITHOUT changing the container's oElementMap definition and behaviour, and WITHOUT supress/disable this warning globally in the project settings as well as WITHOUT changing the afxtempl.h file supplied by VS2010.
Thanks for help:
Andrew
I've replaced it's definition to: CMap<long, long&, T*, T*&> oElementMap;. I was not sure it is the "long-counterpart" of the old map definition, therefore I did several test to compare them.
The solution was finally this.
I am having troubling compiling a MATLAB Mex library - specifically, the 'Correlation Clustering Optimization' code from this website.
I am trying to compile on an OSX machine, and am using the supplied mexall function. This runs the following line:
mex -O -largeArrayDims CXXFLAGS="\$CXXFLAGS -Wno-write-strings" QPBO.cpp QPBO_extra.cpp QPBO_maxflow.cpp QPBO_wrapper_mex.cpp QPBO_postprocessing.cpp -output QPBO_wrapper_mex
The error occurs at linking time with the following output to the MATLAB command line:
ld: duplicate symbol QPBO<int>::GetMaxEdgeNum() in QPBO_extra.o and QPBO.o
collect2: ld returned 1 exit status
mex: link of ' "QPBO_wrapper_mex.mexmaci64"' failed.
Judging from this, the function GetMaxEdgeNum is appearing in both QPBO_extra.o and QPBO.o. However, it is only actually defined in a header file, QPBO.h. I therefore suspect that both source files which include it are including it as a symbol in their object files, causing a problem at link time.
(Further information: Each source file also includes a file #include "instances.inc" at the very end of the file. instances.inc apparently seems to include some specific instantiations of the templated QPBO.)
Is there an obvious mistake I am making here? What can I do to increase my chances of being able to compile this code?
EDIT
This is the definition of the problematic GetMaxEdgeNum function in QPBO.h:
template <typename REAL>
inline int QPBO<REAL>::GetMaxEdgeNum()
{
return (int)(arc_max[0]-arcs[0])/2;
}
EDIT 2
Some more details about my machine:
OSX 10.6.8
MATLAB R2012a (also have R2011b)
g++ 4.2 or g++ 4.0 (or g++ 4.6 via MacPorts)
I've added some details on what I really want from an answer in my 'bounty description' below.
EDIT 3
There's a bit of consensus that instances.inc may be causing the trouble. This is included at the end of each cpp file, and it contains the following:
#include "QPBO.h"
#ifdef _MSC_VER
#pragma warning(disable: 4661)
#endif
// Instantiations
template class QPBO<int>;
template class QPBO<float>;
template class QPBO<double>;
template <>
inline void QPBO<int>::get_type_information(char*& type_name, char*& type_format)
{
type_name = "int";
type_format = "d";
}
template <>
inline void QPBO<float>::get_type_information(char*& type_name, char*& type_format)
{
type_name = "float";
type_format = "f";
}
template <>
inline void QPBO<double>::get_type_information(char*& type_name, char*& type_format)
{
type_name = "double";
type_format = "Lf";
}
It seems like the issue is that some template code is in .cpp files.
Remove the #include instances.inc declarations from the .cpp files.
Move all code from QPBO.cpp, QPBO_extra.cpp, QPBO_maxflow.cpp and QPBO_postprocessing.cpp to the header file qpbo.h.
You'll have now a single .cpp file qpbo_wrapper_mex.cpp and a single header qpbo.h
mex the file (in matlab) using:
>> mex -O -largeArrayDims qpbo_wrapper_mex.cpp
Should work...
Changing GetMaxEdgeNum to a static function, or putting it in an anonymous namespace will probably fix your problem.
The reason is, as you suggest, that it has external linkage in both object files, which results in a nameclash. My suggested solutions gives it internal linkage.
After edit:
Does it change anything if you define the method inside the class definition?
Like this:
template <typename REAL>
class QPB0 {
...
public:
inline int GetMaxEdgeNum()
{
return (int)(arc_max[0]-arcs[0])/2;
}
...
};
I'm using a library that unfortunately, it appears the developer no longer works on or replies to issues in his Git repository. The library is used to drive HT1632C LED matrix drivers, and while it works in 0022/0023, it does not work in Arduino 1.0. When compiled, my Sketch gives the following error:
In file included from Final_code__1_0compatible.cpp:7:
C:\arduino-1.0\libraries\ht1632c/ht1632c.h:182: error: conflicting return type specified for 'virtual void ht1632c::write(uint8_t)'
C:\arduino-1.0\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
Referencing this site: http://arduino.cc/forum/index.php?topic=82450.0, I found a comment from someone who had the same compilation errors I did (but with another library). It looks like their fix was to replace something with "size_t"
Line 200: size_t write(uint8_t); //changed to resolve conflict with print.h
The conflicting lines in the library's .h and .cpp files look to be:
.h:
void write(uint8_t chr);
.cpp:
void ht1632c::write(uint8_t chr)
{
byte x, y;
if (chr == '\n') {
//y_cur += font_height;
} else {
//x_cur += putchar(x_cur, y_cur, chr, GREEN, PROPORTIONAL);
//x_cur = 0;
//y_cur = 0;
}
//sendframe();
}
I'm not a C/C++ expert, but am I correct, in that if I change the .h to be "size_t write(uint8_t chr)" and the .cpp to be "size_t ht1632c::write(uint8_t chr)" that this will work?
I tried doing it, and it compiles, but I don't know if I replace the word "void" with "size_t", or if I need to replace the "uint8_t" with "size_t".
so,
size_t ht1632c::write(uint8_t chr)
is the right function change. You should also add a
return 1;
right after the
sendframe();
line. write is expected to return the number of characters successfully written, as you don't have any way in the code as pasted to determine if there is an error in the writing, you should just say it worked.