warning: XXXX has different visibility (default) in YYYY and (hidden) in ZZZZ - iphone

I am trying to make an iPhone app that uses OpenCV plus another C++ Library.
It seems to compile and link fine. It actually works.
Is just I want to get rid of this ugly warning:
ld: warning: std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&)has different visibility (default) in /Users/nacho4d/Documents/Projects/iOS/iAR/opencv_device/lib/libcxcore.a(cxdatastructs.o) and (hidden) in /Users/nacho4d/Documents/Projects/iOS/iAR/build/iAR.build/Debug-iphoneos/iAR.build/Objects-normal/armv6/combination.o
What does it mean?, How can I solve it?
just in case, this is the header of combination class, from the library I mentioned.
//combination.h
typedef std::vector<int> combi;
typedef std::vector< combi > allcombi;
class Combination
{
public:
void Init(const int n, const int m);
allcombi::iterator begin();
allcombi::iterator end();
allcombi::const_iterator begin() const;
allcombi::const_iterator end() const;
private:
void Nest(int nest, int column, int n1, int n2, int k[], allcombi &result);
private:
allcombi m_data;
};
Thanks in advance
Ignacio

It seems libcxcore.a and combination.o are compiled with different symbol visibility options.
Read about symbol visibility there.
So, I guess you just need to compile combination.cpp with -fvisibility=default flag. If you use XCode, check "Symbols Hidden by Default" setting in "GCC - Code Generation" section. It should be unchecked for both projects.

Related

Can Sal annotate that parameter members may be mutated?

I am writing a reference-counted linked list of characters data structure in C for practice. I want to try using Sal in it to annotate function parameters for this practice.
I have an input paremeter(named This), which I want to annotate to make it clear that the specified parameter's members must be mutable in order for the function to behave as expected.
The situation is analogous to the code below.
#include <Windows.h>
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_In_ Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Is there an existing Sal annotation that can be used to annotate the This parameter of the Box_increment function to make it clear from the function signature that the function modifies one or more members of the Box that has been passed to it?
Something like _InternallyMutable_(but exist):
#include <Windows.h>
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_InternallyMutable_ _In_ Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Best solution so far(unfortunately, there does not seem to be any equivelent in SAL to denote Internally_mutable, there is Unchanged which is the opposite):
#include <Windows.h>
#define _Internally_mutable_(expr) _At_(expr, _Out_range_(!=, _Old_(expr)))
typedef struct Box {
ULONG val;
} Box;
ULONG Box_decrement(_In_ _InternallyMutable_(This) Box *This) {
return InterlockedDecrement(&(This->val));
}
int main(int argc, char **argv) {
Box b = {2};
Box_decrement(&b);
return (BYTE)b.val;
};
Yes! You can. SAL is a wonderful DSL that lets you do basically anything you want if you're psychic enough to infer it from the little bits in the Windows SDK. I've even in the past been able to write super simple custom annotations to detect invalid HANDLE usage with _Post_satisfies_ and friends.
This code seems to work:
_At_(value, _Out_range_(!=, _Old_(value)))
void change_value_supposed_to(int& value) noexcept {
//value += 1;
}
...Running with all native rules in code analysis, I get a warning like this:
Warning C28196 The requirement that '_Param_(1)!=(("pre"), _Param_(1))' is not satisfied. (The expression does not evaluate to true.)
(there, substitute value with your variable)
For _Internally_mutable_, I can do it in the "above the function" style of SAL:
#define _Internally_mutable_(expr) _At_(expr, _Out_range_(!=, _Old_(expr)))
_Internally_mutable_(value)
void change_value_supposed_to_internally_mutable(int& value) noexcept {
//value += 1;
(void)value;
}
...but not inline WITHOUT being repetitive, as you wanted. Not sure why right now - _Curr_ doesn't seem to be working? - I may need another layer of indirection or something. Here's what it looks like:
#define _Internally_mutable_inline_(value) _Out_range_(!=, _Old_(value))
void change_value_supposed_to_internally_mutable_inline(_Internally_mutable_inline_(value) int& value) noexcept {
//value += 1;
(void)value;
}
How I figured this out:
sal.h defines an _Unchanged_ annotation (despite doing web dev for several years now and little C++, I remembered this when I saw your question in a google alert for SAL!):
// annotation to express that a value (usually a field of a mutable class)
// is not changed by a function call
#define _Unchanged_(e) _SAL2_Source_(_Unchanged_, (e), _At_(e, _Post_equal_to_(_Old_(e)) _Const_))
...if you look at this macro closely, you'll see that it just substitutes as:
_At_(e, _Post_equal_to_(_Old_(e)) _Const_)
...and further unrolling it, you'll see _Post_equal_to_ is:
#define _Post_equal_to_(expr) _SAL2_Source_(_Post_equal_to_, (expr), _Out_range_(==, expr))
Do you see it? All it's doing is saying the _Out_range_ is equal to the expression you specify. _Out_range_ (and all the other range SAL macros) appear to accept all of the standard C operators. That behavior is not documented, but years of reading through the Windows SDK headers shows me it's intentional! Here, all we need to do is use the not equals operator with the _Old_ intrinsic, and the analyzer's solver should be able to figure it out!
_Unchanged_ itself is broken?
To my great confusion, _Unchanged_ itself seems broken:
_Unchanged_(value)
void change_value_not_supposed_to(_Inout_ int& value) noexcept {
value += 1;
}
...that produces NO warning. Without the _Inout_, code analysis is convinced that value is uninitialized on function entry. This makes no sense of course, and I'm calling this directly from main in the same file. Twiddling with inlining or link time code generation doesn't seem to help
I've played a lot with it, and various combinations of _Inout_, even _Post_satisfies_. I should file a bug, but I'm already distracted here, I'm supposed to be doing something else right now :)
Link back here if anybody does file a bug. I don't even know what the MSVC/Compiler teams use for bug reporting these days.
Fun facts
5-6 years ago I tried to convince Microsoft to open source the SAL patents! It would have been great, I would have implemented them in Clang, so we'd all be able to use it across platforms! I might have even kicked off a career in static-analysis with it. But alas, they didn't want to do it in the end. Open sourcing them would have meant they might have to support it and/or any extensions the community might have introduced, and I kinda understand why they didn't want that. It's a shame, I love SAL, and so do many others!

How to declare double const* const* variable in cython?

I have a c++ function in "example.h":
bool myFunc(double const* const* p);
and I want to wrap it with cython code (in .pyx file).
Howerver, when I'm write the following code:
cdef extern from r"example.h":
bool myFunc(double const*const* p)
I'm receiving the following error:
Error compiling Cython file:
Expected ')', found '*'
and pycharm shows this error on double const* const* p:
Unresolved reference 'const'
How can I declare that kind of variables?
In C/C++, there is ongoing battle where to put the const-qualifier: either
void foo(const int *a);
or
void foo(int const *a);
both meaning the same thing.
There is no such battle in Cython, because it accept only the first version.
The above rule, applied to double** leads to:
cdef extern from r"example.h":
bool myFunc(const double * const* p)
Or as a work-around one could drop the const-qualifier altogether:
cdef extern from r"example.h":
bool myFunc(const double **p)
which I would not recommend, all above in large projects, where using const-qualifiers helps a lot when figuring out what happens.

Eclipse Luna CDT: What is a header variant?

I am having difficulty getting the Eclipse Indexer (Codan) to recognize certain data declarations in header files. There is a new preference to Index all header variants, but little explanation as to what this means. Enabling the preference seems to fix the problem. But I still would like to know what the preference does exactly.
Let's say you have header a.h like this:
#pragma once
#ifndef SYMBOL
#define SYMBOL int
#endif
struct S
{
SYMBOL sym;
};
And now if you include your header like this:
struct UserSymbol
{
int i, j, k;
};
#define SYMBOL UserSymbol
#include "a.h"
S var;
int main()
{
var.sym.i = 123;
return 0;
}
then Eclipse CDT may not to recognize sym.i.
You may have more complex examples with deeper nested inclusions or so on.
EDIT:
But if you include the a.h to the "Index all variants of specific headers" list or check "Index all header variants" Eclipse will build several variants of the a.h indexes and will "know" that you have defined the your specific SYMBOL.

Strange LLVM warning: no previous prototype for function for

If I missed the prototype, XCode (LLVM) prompt me for error
no previous prototype for function for exceptionHandler
But why they are needed in my code below?
void exceptionHandler(NSException * exception); // Why this Line is needed?
void exceptionHandler(NSException * exception)
{
// ....
}
#implementation AppDelegate
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
NSSetUncaughtExceptionHandler(&exceptionHandler);
...
From the GCC manual:
-Wmissing-prototypes (C and Objective-C only)
Warn if a global function is defined without a previous prototype declaration. This warning is issued even if the definition itself provides a prototype. The aim is to detect global functions that fail to be declared in header files.
Clang borrowed this option for GCC compatibility, and because it's useful (I would presume this of the Clang devs).
The option exists so you can prevent yourself from making a common mistake which may be easily avoided. It's nice to be explicit about visibility/linkage for clarity/intent's sake.
In short, you've asked the compiler to tell you when an unqualified definition does not match a declaration by enabling this option. You should either qualify that as extern and make it usable to others (e.g. put it in a header), or declare it static. If using C++ inline is also an option.
Of course, implicit visibility is well known, but I typically find the option useful in these scenarios:
1) I made a typo:
// file.h
extern void MONExceptionHandler(NSException * exception);
and
// file.m
void MONExceptionhandler(NSException * exception) {
…
2) I should be explicit about the symbol's visibility:
// file.m
static void MONExceptionHandler(NSException * exception) {
…
3) I forgot to #include the header which declared the function:
// file.h
extern void MONExceptionHandler(NSException * exception);
Warning:
// file.m
void MONExceptionHandler(NSException * exception) {
…
No Warning:
// file.m
#include "file.h"
void MONExceptionHandler(NSException * exception) {
…
So there's the rationale, history, and some examples - again, -Wmissing-prototypes is an option. If you trust yourself to work with it disabled, then do so. My preference is to be explicit, and to let programs detect potential and actual issues so I don't have to do it manually.
If you're declaring a function only for use within this file, prefix the declaration with the static keyword and the warning will go away. As it is, you're declaring a global function; theoretically it could be called from anywhere within your app. But as you've given it no prototype, nobody else could call it.
So the warning, as I understand it, is trying to make you clarify your intentions between static functions and global functions, and discourage you from declaring a global function when you meant to declare only a static one.
I think this is most useful for C++ code. For example I have header
class MyClass {
public:
void hello();
};
and .cpp file
void hello() {
cout << "hello";
}
And you will see the warning because there are no prototype for function void hello(). In case the correct implementation should be
void MyClass::hello() {
cout << "hello";
}
So this warning make sure you are implementing the function that you are aware of (not miss typed a name or different argument format).
That warning is alerting that you can't call your method from another method that is written above. In C, the order of the declaration/implementation minds a lot and gives the difference between something that you can access or you can't.

Eclipse undefined reference

I'm using Eclipse and MinGW. I've got undefined reference to error to all that I write in h files, that I do include in cpp-file where main located. I create an empty project, and the same thing again (
main.cpp
#include <iostream>
#include "Stack.h"
using namespace std;
int main(){
Stack<int> stack(10);
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
stack.h
#ifndef STACK_H_
#define STACK_H_
template <class T>
class Stack{
private:
struct StackEl;
StackEl *top;
public:
Stack();
Stack(T el);
~Stack();
void Push(const T& el);
T Pop();
};
#endif /* STACK_H_ */
and stack.cpp inplements everything from stack.h
If I include not h-file, but cpp - all works. Help please!
I've got following errors
D:/Workspacee/Stack2/Debug/../src/Stack2.cpp:16: undefined reference to `Stack<int>::Stack(int)'
D:/Workspacee/Stack2/Debug/../src/Stack2.cpp:18: undefined reference to `Stack<int>::~Stack()'
D:/Workspacee/Stack2/Debug/../src/Stack2.cpp:18: undefined reference to `Stack<int>::~Stack()'
This is a linker error. I'm no Eclipse expert, but you have to tell it somehow to add Stack.o to the linking command.
If you include Stack.cpp instead of Stack.h, the implementations from the cpp-file get included into main.cpp by the preprocessor before compilation, so the linking stage has no unresolved references to outside functions.
My bad, that is becouse templates! When you use template, all code, including realization of functions, must be in header-file, or you have to write prototypes for every type you are going to use you template-functions with. I've forgot about that working with templates is not the same as with usual function :(