I need to create a predicate from bound member function, so I wrapped it in a boost::function<bool(SomeObject const &)>. That seems to be fine and everything, but I also needed to negate it in one case. However
boost::function<bool(SomeObject const &)> pred;
std::not1(pred);
does not compile under MSVC++ 9.0 (Visual Studio 2008), complaining that reference to reference is invalid:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : warning C4181: qualifier applied to reference type; ignored
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : error C2529: '_Left' : reference to reference is illegal
The problem is that boost::function defines the argument_type as SomeObject const & and the std::unary_negate<_Fn1> instantiated by std::not1 internally tries to use const typename _Fn1::argument_type& and compiler rejects it because T::argument_type is already a reference. I am certain that that should compile under C++11, but this is old compiler that is C++03 only. So I'd like to know who's fault it is:
the compiler's, because it should collapse the reference (apparently not),
the standard library's, because it should be prepared to handle functors taking references (apparently not, because the specification defines unary_negate with const typename Predicate::argument_type& x argument),
boost's, because argument_type shouldn't be reference even when the actual argument is or
mine, because boost::function shouldn't be used with reference arguments?
The fault is certainly not Boost's; boost::function is basically just std::function, with all the same semantics. And boost::functions with reference parameters work fine, too. You just can't use them with std::not1 or the rest of the <functional> stuff.
C++11's reference-collapsing makes std::not1 work the way you would think it ought to. The way std::not1 was specified in C++03 couldn't possibly work without reference-collapsing — except in implementations where the implementors did a little bit of creative interpretation rather than slavishly following the letter of the Standard.
It's possible to make std::not1 work in C++03 by adding a specialization of std::unary_negate for predicates with reference argument_types, but neither libc++ nor libstdc++ has done so.
But you know who has? Boost! If you just change your code to use boost::not1 everywhere you currently use std::not1, everything will work fine. Basically, think of the boost namespace as if it were a C++11-compliant version of std; anything that works in C++11's std namespace probably works in C++03's boost namespace.
Caveat, hopefully off-topic: The Clang compiler on my Macbook (Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)) silently collapses references even in -std=c++03 mode, so that
typedef const int& ref;
typedef const ref& ref2;
produces no error. When you test your C++03 code, make sure you're not using a compiler with this misfeature.
Related
While compiling and Xcode swift project for MacOS, not used functions are removed from the binary (removed by the optimizer I guess). Is there a way to tell the compiler to not remove unused functions, perhaps with a compiler option (--force-attribute?) so that even with optimization enabled those functions remain in the binary?
I know that if a global function is declared as public (public func test()) then it's not removed even if not used (Since it can be used by other modules), but I can't use public since that would export the symbol for that function.
Any suggestion?
If this is indeed removed by the optimiser, then the answer is two-fold.
The optimiser removes only things that it can prove are safely removable. So to make it not remove something, you remove something that the optimiser uses to prove removability.
For example, you can change the visibility of a function in the .bc file by running a pass that makes the functions externally callable. When a function is private to the .bc file (also called module) and not used, then the compiler can prove that nothing will ever call it. If it's visible beyong the .bc file, then the compiler must assume that something can come along later and call it, so the function has to be left alive.
This is really the generic answer to how to prevent an optimisation: Prevent the compiler from inferring that the optimisation is safe.
Writing and invoking a suitable pass is left as an exercise for the reader. Writing should be perhaps 20 lines of code, invoking… might be simple, or not, it depends on your setting. Quite often you can add a call to opt to your build system.
As I discovered, the solution here is to use a magic compiler flag -enable-private-imports (described here: "...Allows this module's internal and private API to be accessed") which basically add the function name to the list #llvm.used that you can see in the bitcode, the purpose of the list is:
If a symbol appears in the #llvm.used list, then the compiler,
assembler, and linker are required to treat the symbol as if there is
a reference to the symbol that it cannot see (which is why they have
to be named)
(cit.) As described here.
This solves my original problem as the private function even if not used anywhere and not being public, during compilation is not stripped out by the optimiser.
I am working on an Android application that uses OpenCV 2.4.9 and NDKr9 as dependecies. I also use Eclipse 4.4 Luna as the IDE, with CDT plugin 8.4 installed.
Whenever I'm trying to use the methods std::vector.at(int), or the "[]" method, i get weird errors. For instance, consider the code:
#include <vector>
.........................
struct CustomStruct {
int level;
Point firstPoint, secondPoint, middlePoint;
};
.........................
int maxElemNr = 10;
std::vector<CustomStruct > customStructVector(maxElemNr);
.........................
for(int i=0;i<customStructVector.size();i++){
if(customStructVector.at(i).level == 0){
}
}
At customStructVector.at(i) Eclipse tells me the following:
Invalid arguments ' Candidates are: ResultWithEvidence & at(?) const
ResultWithEvidence & at(?)'
If I want to use the "[]" operator, instead of the "at(index)" method, i get the following:
resultWithEvidenceVector[i].level tells me that the field level is not found.
I am by no means an expert C/C++ coder, and I am rather new at working with the NDK. Coming from a Java background, I was expecting to get an object of type CustomStruct when calling either customStructVector.at(i) or customStructVector[i], such that I could then simply access the field level on my object, to read its value.
Also, declaring my vector as
int maxElemNr = 10;
std::vector<CustomStruct> customStructVector;
customStructVector.reserve(maxElemNr);
I get:
Invalid arguments ' Candidates are: void reserve(?) '
I have searched for answers, and came with the theory that eclipse might not use the c++11 version of the std library?
I've read about the vector class from here. Also, this issue closely resembles the question asked here.
Will provide more info about my environment and such, if needed. Would like to solve this, as it's quite a blocker for my project as of now..
What am I doing wrong? I had no problems compiling and running the code previously to using the std::vector class.
LE: apparently the workaround &(resultWithEvidenceVector.data()+i)->level is recognized by the editor, and the code compiles. Would still like to use the std::vector as it is supposed to be used though.
I had the same problem. It works in Visual Studio compiler but when i try to access vector element i get exactly the same error.
However it seems that if you don't use 'at' then it works for example customStructVector.at(i) use customStructVector(i),
It is strange. I didn't test it in detail. Please note that if you have vector you have to cast the result in order to access the type members.
Regards
I have a third party DLL in C++ that I'd like to replace with one I've made myself...
This is a clean room type exercise just for learning purposes ; and I am hoping to make a replacement DLL that can be used with programs linked against the original DLL -- without recompiling the applications.
I am using the same visual studio compiler version (9) used to make the original DLL, but I do not have the original source code for the DLL.
The DLL consists of a C++ class, and some extern "C" functions to handle constructor/destructors, so that all memory management is isolated to the DLL.
I used dependency walker to inspect the original DLL, and demangle/undecorate the linker symbols -- and have attempted to write prototypes for the class and methods ; and then I wrote a python script to take the object code compiled from my class -- and make a .def file that chooses the closest mangled symbols from MY obj code compared against the original DLL exports; ( Allows some qualifier variations, but not name variations ) and then I build a DLL from my obj code using that .def file to have an identical ABI ordering in the DLL.
I am at the stage where dependency walker can not tell the difference between my DLL and the original when it comes to listing the types -- although there are small differences in several of the mangled names that I would like to resolve...
One member is very troublesome to figure out as it is not a function, but supposedly member data eg: a decorated ?pzSambaAddress#HWInterface##2PBDB shows up as:
char const * const HWInterface::pzSambaAddress ; // in dependency walker
And I'm not sure if dependency walker is decoding the mangling wrong or not, because
I can't figure out how to implement anything even remotely like this in my header file which would export a symbol to an .obj file, let alone to a DLL.
What kinds of definitions could create something like that?
If I type it in (as shown above) to my header file, it's a constant string -- therefore I'm thinking it has to be initialized in the constructor methods, something like this:
HWInterface::HWInterface(HWInterface const & iface) : pzSambaAddress("dummy") {
std :: cout << this -> pzSambaAddress; // access it, to force compiler
}
But when I compile that, pzSambaAddress, does not show up in the obj file at all.
Obviously because it's not an allocated memory location prior to class instantiation.
eg: dumpbin /SYMBOLS HWInterface.obj | grep "pzSam" finds nothing.
I could add the static keyword to the definition of pzSambaAddress and initialize it exactly once for the whole class.
char const * const HWInterface::pzSambaAddress="a samba name constant.";
The name then mangles to: ?pzSambaAddress#HWInterface##2QBDB
But dependency walker doesn't say it's static... Nor is mangled ##2QBDB quite ##2PBDB... and that will also mean that I can also no longer initialize individual instances with constructors.
HWInterface.cpp(25) : error C2438: 'pzSambaAddress' : cannot initialize static class data via constructor
So Q1: Is a static constant the cause of the exported symbol, and dependency walker just doesn't say "static" -- or are there other ways it could be generated / initialized ?
Secondly:
Is there anything better at demangling, and giving information on esoteric qualifiers?
When I run dumpbin on an object file, I get all kinds of qualifiers that dependency walker doesn't show (on other symbols, not the example we've been talking about).
dumpbin.exe /symbols myOwnFile.obj
But as I don't have the obj file for the original DLL, nor the .lib, that switch doesn't work. Running dumpbin.exe /symbols on the DLL gives me nothing.
Running dumpbin.exe /exports on the DLL merely gives me the mangled names.
There is also a VC++ console application "undname.exe", but often it doesn't undecorate the name passed on the command line at all, but gives most of the name back still mangled.
I looked around a lot on the web, but am finding only partially accurate/incomplete information, which wasn't enough to solve the problem I just showed.
Wikipedia on mangling names
Any ideas of where to find a more verbose/accurate demangler program for visual C++ ?
class HWInterface {
public:
__declspec(dllexport)
static char const * pzSambaAddress;
};
char const* HWInterface::pzSambaAddress = "hello";
Then:
C:\temp>cl /LD test.cpp
...
C:\temp>dumpbin /exports test.dll
...
Dump of file test.dll
...
ordinal hint RVA name
1 0 00008000 ?pzSambaAddress#HWInterface##2PBDB
You can use the undname utility included with MSVC to decode mangled names:
C:\temp>undname ?pzSambaAddress#HWInterface##2PBDB
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?pzSambaAddress#HWInterface##2PBDB"
is :- "public: static char const * const HWInterface::pzSambaAddress"
However, you'll note that undname says that there should be an extra const in there. As you saw, adding that extra const gets you a slightly different mangled name (with a 'Q' instead of a 'P' near the end:
Using static char const * const instead of static char const * produces ?pzSambaAddress#HWInterface##2QBDB
undname imports a function from the C runtime, _unDNameEx, that I assume is used to demangle names (and I assume that Dependency Walker uses it, too - apparently via an interface in DBGHELP.DLL). Looks like there's a bug in the demangler.
The GNU tools have a similar utility, c++filt, to decode g++ mangled names.
I've seen several conflicting descriptions of how to do this around the google results, and haven't been able to get any of them to work.
My problem is basically this: where I call ExecutionEngine::getPointerToFunction (with an llvm::Function*), I'd like to instead get the pretty-printed x86 assembly that would be produced for this function.
Anybody?
[ETA: I'm using LLVM 3.3. The descriptions I've found seem to be for earlier versions of LLVM.]
It turns out that you can add an event listener to a JIT ExecutionEngine with ExecutionEngine::RegisterJITEventListener. If you provide an instance of that class, you can have your callback invoked when machine code is generated for you, and you'll be given a pointer to the machine code and its length. With this, you can call llvm::sys::disassembleBuffer to get a description of the machine code buffer.
However, the llvm::sys::disassembleBuffer function just defers to the udis library if LLVM was compiled with that support. Since my build of LLVM didn't have this flag set and I can't rebuild it, I'll just look into using the udis library directly:
https://github.com/vmt/udis86
I have a workspace built using MS-Visual Studio 2005 with all C code.In that i see many functions which are not called but they are still compiled(they are not under any compile time macro to disable them from compiling).
I set following optimization settings for the MS-VS2005 project to remove that unused code:-
Optimization level - /Ox
Enable whole program optimization - /GL
I tried both Favor speed /Ot and Favor Size /Os
Inspite of all these options, when i see the linker generated map file, I see the symbols(unsed functions) names present in the map file.
Am I missing something? I want to completely remove the unused code.
How do I do this?
The compiler compiles C files one-at-a-time. Therefore, while compiling a C-file that does contains an unused function, the compiler cannot be sure that it will not be called from another file and hence it will compile that function too. However, if that function were declared as static (file-scope), then the compiler would know it is not used and hence remove it.
Even with whole program optimization, I think it would still not be done since the compilation could be for a library.
Linkers do something similar to what you are looking for. If your code links against a library containing multiple objects, then any objects that do not contain functions used by your code (directly or indirectly) would not be included in the final executable.
One option would be to separate your code into individual libraries and object files.
PS - This is just my guess. The behavior of the compiler (with whole program optimization) or linker essentially depends on the design choices of that particular compiler or linker
On our projects we have a flag set under the project properties\Linker\Refrences. We set it to Eliminate Unreferenced Data (/OPT:REF), according to the description this is supposed to remove function calls or data that are never used. I am just going by the description, I have never tested this or worked with it. But I just happened to see it within the last hour and figured it might be something you could try.