Hi I'm trying to find out what is and isn't possible with C++ on BrewMP.
Does anybody have first hand experience of using C++ with Brew, specifically BrewMP, and can say if they have managed to get these things working on a device without too much hassle:
static variables/functions
templates
exceptions
casting
etc.
Before in Brew3.X, global and static variables are not supported. However in Brew MP, there is an ELF2MOD tool. With this, you can use global and static varaibles.
See your SDK path such as:
C:\Program Files\Qualcomm\Brew MP SDK\Toolset 7.10 Rev 10.0.1489821\bin
If your global or static data is non-POD (a C++ object, which has to call C++ class constructor), please don't use it. See
https://developer.brewmp.com/forum/using-static-variables-classes-0
Standard C Library (stdc lib, or c runtime) are absolutely prohibited in BrewMP, such as memset and sprintf. Cause: In a general process module with main() entry, those of C runtime are already initialized automatically before user's code calling them. BrewMP mod (mod1) files are dynamically loaded and linked. There are no appropriate time to call initialization, and these MODs should not call C runtime initialization individually.
C++ template functions and template classes: template code instantiation are generted at compile-time, and they don't need any load-time and run-time code initialization. They can be used safely in device.
C++ Exceptions: I didn't tested it. In the default ARM compiler options, exception are not turned on. And the exceptions need the enablement of C++ RTTI.
C++ cast: dynamic_cast is the big problem, because it needs support run-time type identification enabled, and doing type checking at run time. Other casts, such as static_cast, reinterpret_cast, and const_cast, are only a hint for compiler to check at compile-time.
There were some problems with:
Virtual or abstract methods
Static and global variable support
Static initialization of global
objects
Most of them can be solved using custom post-linker. It worked fine for me, hope it`s suitable for you too.
Related
I have the following piece of code which is a part of api (cdecl). In MSVC++ the sizeof bool is 1 byte, but since bool is implementation defined, some programs compiled by other compiler/the author incorrectly define function signature may treat bool as >1 byte and calling the check below may return true on their side of programs.
virtual bool isValid()
{
return false;
// ^ code above in asm: xor al, al
}
To avoid this, I put an inline asm, xor eax, eax before the return - but I feel it a bit hacky and it of course will not work on x64 due to lack of inline assembler support.
Using #define bool int will work but it is not I wanted, as I have structs that have bool datatype inside it and using this will causes corruption.
Is there anything like intrinsics that can zeroed the eax/rax register or anything that can solve this problem?
There's nothing that will do what you're asking for. Your problem needs a much different solution.
First any code that "incorrectly define function signature" is broken an needs to fixed. It's never the solution to work around it in other code.
Next your problem is like more than just bool being implementation defined, the C++ standard makes a whole host of things are implementation defined. So much so that two different C++ compilers are rarely have a compatible ABIs. If your code provides C++ interfaces for the use of code compiled by other people you'll probably need to produce separately compiled binaries, whether in the form of object files, static libraries, DLLs or executables, for each different compiler you want to support. In fact you may need to provide separate binaries for each version of each compiler.
There are two C++ compilers the try to be compatible with the Microsoft C++ ABI. The first is Intel's C++ compiler and the second is the Windows port of clang. The clang implementation is notably still a work in progress. You may still need to create separate versions for each version of the Microsoft C/C++ runtime libraries your code is compiled with.
You can potentially reduce the number of different versions of binaries that you need to distribute by providing a pure C interface to your code. A pure C interface means using only C data types and only functions declared as extern "C". While things like classes, member functions, templates, RTTI and exceptions can be used in your implementation the can't be used as part of your public interface. An exception are COM-like interfaces, classes with nothing but public pure virtual functions. Since C compilers for Windows all use essentially the same C ABI and support COM interfaces, compatibility issues are less likely to be an issue. However the bool type (actually the _Bool type in C) is probably not safe to use, since it's a relatively recent addition to the C language. Use int in your C interfaces instead.
Note that because of C/C++ runtime differences even if you all you want to do distribute compiled binaries for use with Microsoft's Visual C++ compiler you may still need to distribute versions for each version of the compiler. That's because each version comes with a different runtime implementation and which have data structures with incompatible internal layouts. You can't pass an STL container created in a function compiled by one version of Visual C++ to a function compiled with a different version. You can't allocate memory with malloc in an executable and free it in a DLL, if the executable and DLL use different versions of the C runtime.
Unfortunately unless you're willing to restrict your users to one particular compiler the easy solution to your problem that you're looking for may not exist. Note that this is a common solution used by programs that provide plugin support. Pugins need to be compiled the same version of the same compiler that compiled the executable.
The format of the output of type_info::name() is implementation specific.
namespace N { struct A; }
const N::A *a;
typeid(a).name(); // returns e.g. "const struct N::A" but compiler-specific
Has anyone written a wrapper that returns dependable, predictable type information that is the same across compilers. Multiple templated functions would allow user to get specific information about a type. So I might be able to use:
MyTypeInfo::name(a); // returns "const struct N::A *"
MyTypeInfo::base(a); // returns "A"
MyTypeInfo::pointer(a); // returns "*"
MyTypeInfo::nameSpace(a); // returns "N"
MyTypeInfo::cv(a); // returns "const"
These functions are just examples, someone with better knowledge of the C++ type system could probably design a better API. The one I'm interested in in base(). All functions would raise an exception if RTTI was disabled or an unsupported compiler was detected.
This seems like the sort of thing that Boost might implement, but I can't find it in there anywhere. Is there a portable library that does this?
There are some limitations to do such things in C++, so you probably won't find exactly what you want in the near future. The meta-information about the types that the compiler inserts in the compiled code is also implementation-specific to the RTL used by the compiler, so it'd be difficult for a third-party library to do a good job without relying to undocumented features of each specific compiler that might break in later versions.
The Qt framework has, to my knowledge, the nearest thing to what you intended. But they do that completely independent from RTTI. Instead, they have their own "compiler" that parses the source code and generates additional source modules with the meta-information. Then, you compile+link these modules along with your program and use their API to get the information. Take a look at http://doc.qt.nokia.com/latest/metaobjects.html
Jeremy Pack (from Boost Extension plugin framework) appears to have written such a thing:
http://blog.redshoelace.com/2009/06/resource-management-across-dll.html
3. RTTI does not always function as expected across DLL boundaries. Check out the type_info classes to see how I deal with that.
So you could have a look there.
PS. I remembered because I once fixed a bug in that area; this might still add information so here's the link: https://stackoverflow.com/a/5838527/85371
GCC has __cxa_demangle https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
If there are such extensions for all compilers you target, you could use them to write a portable function with macros to detect the compiler.
I want to use C with templates on a embedded environment and I wanted to know what is the cost of compiling a C program with a C++ compiler?
I'm interested in knowing if there will be more code than the one the C compiler will generate.
Note that as the program is a C program, is expect to call the C++ compiler without exception and RTTI support.
Thanks,
Vicente
The C++ compiler may take longer to compile the code (since it has to build data structures for overload resolution, it can't know ahead of time that the program doesn't use overloads), but the resulting binary should be quite similar.
Actually, one important optimization difference is that C++ follows strict aliasing rules by default, while C requires the restrict keyword to enable aliasing optimizations. This isn't likely to affect code size much, but it could affect correctness and performance significantly.
There's probably no 'cost', assuming that the two compilers are of equivalent quality. The traditional objection to this is that C++ is much more complex and so it's more likely that a C++ compiler will have bugs in it.
Realistically, this is much less of a problem that it used to be, and I tend to do most of my embedded stuff now as a sort of horrible C/C++ hybrid - taking advantage of stronger typing and easier variable declaration rules, without incurring RTTI or exception handling overheads. If you're taking a given compiler (GCC, etc) and switching it from C to C++ mode, then much of what you have to worry about is common to the two languages anyway.
The only way to really know is for you to try it with the compilers you care about. A quick experiment here on a trivial program shows that the output is the same.
Your program will be linked to the C++ runtime library, not the C one. The C++ is larger as well.
Also, there are a couple of differences between C and C++ (aliases were already pointed out) so it may happen that your C code just does not compile in C++.
If it's C, then you can expect it will be exactly the same.
To elaborate: both C and C++ will forward their parse tree into the same backend that generates code (possibly via another intermediate representation), which means that if the code is functionally identical, the output will look the same (or nearly so).
Templates do "inflate" code, but you would otherwise have to write the same code or use macros to the same effect, so this is no "extra cost". Contrarily, the compiler may be able to optimize templates better in some cases.
A C++ compiler cannot compile C code. It can only compile C++, including a very ugly language which is the intersection of C and C++ and the worst of both worlds. Some C code will fail to compile at all on a C++ compiler, for example:
char *s = malloc(len+1);
While other C code will be compiled to the wrong thing, for example:
sizeof 'a'
I have found this extra-ordinary document Technical Report on C++ Performance. I have found there all the answers i was looking for.
Thanks to all that have answered this question.
There will be more code because that is what templates do. They are a stencil for generating (more) code.
Otherwise, you should see no differences between compiling a C program with a C compiler versus compiling with a C++ compiler.
If you don't use any of the extra "features" there should be no difference in size or behavior of the end result.
Although the C code will likely compile to something very similar (assuming there's no exception support enabled), using templates can very rapidly result in large binaries - you have to be careful, because every template instantiation can recursively result in other templates being implicitly instantiated as well.
There was a time when the C++ compiler linked in a bunch of C++ stuff even if the program didnt use it and you would see binaries that were 10 to 100 times larger than the C compiler would produce. I think a lot of that has gone away.
Since this is tagged "embedded", I assume its for embedded systems?
In that case, the major difference between C and C++ is the way C++ treats structs. All structs will be treated like classes, meaning they will have constructors.
All instances of structs/classes declared at file scope or as static will then have their constructors called before main() is executed, in a similar manner to static initialization, which you already have there no matter C or C++.
All these constructor calls at bootup is a major disadvantage in efficiency for embedded systems, where the code resides in NVM and not in RAM. Just like static initialization, it will create an ugly, undesired workload peak at the start of the program, where values from NVM are copied into the RAM.
There are ways around the static initialization in C/C++: most embedded compilers have an option to disable it. But since that is a non-standard setup, all code using statics would then have to be written so that it never uses any initialization values, but instead sets all static variables in runtime.
But as far as I know, there is no way around calling constructors, without violating the standard.
EDIT:
Here is source code executed in one such C++ system, Freescale HCS08 Codewarrior 6.3. This code is injected in the user program after static initialization, but before main() is executed:
static void Call_Constructors(void) {
int i;
...
i = (int)(_startupData.nofInitBodies - 1);
while (i >= 0) {
(&_startupData.initBodies->initFunc)[i](); /* call C++ constructors */
i--;
}
...
At the very least, this overhead code must be executed at program startup, no matter how efficient the compiler is at converting constructors into static initializtion.
C++ runtime start-up differs slightly from C start-up because it must invoke the constructors for global static objects before main() is called. This call loop is trivial and should not add much.
In the case of C++ code that is also entirely C compilable no static constructors will be present so the loop will not iterate.
In most cases apart from that, you will normally see no significant difference, in C++ you only pay for what you use.
Hi i have to port some stuff written on c++ from unix bases os to windows visual studio 2008.
The following code implements array data type with void ** - pointer to the data.
struct array
{
int id;
void **array; // store the actual data of the array
// more members
}
When i compile with g++ on Unix it's ok but when i try with MSVS 2008 I get the error - error C2461: 'array' : constructor syntax missing formal parameters. When i change the member from 'array' to something else it works, so it seems that the compiler thinks that the member name 'array' is actually the constructor of the struct array. It's obviously not a good practice to name the member like the struct but it's already written that way. Can i tell the MSVS compiler to ignore this problem or i should rename all members that are the same as the struct name.
You are dealing with a bug in GCC compiler. C++ language explicitly prohibits having data members whose name is the same as the name of the class (see 9.2/13). MS compiler is right to complain about it. Moreover, any C++ compiler is required to issue a diagnostic message in this case. Since GCC is silent even in '-ansi -pedantic -Wall' mode, it is a clear bug in GCC.
Revison: What I said above is only correct within the "classic" C++98 specification of C++ language. In the most recent specification this requirement only applies to static data members of the class. Non-static data members can now share the name with the class. I don't know whether this change is already in the official version of the revised standard though.
That means that both compilers are correct in their own way. MS compiler sticks to the "classic" C++98 specification of the language, while GCC seems to implement a more recent one.
I'd say that if you're doing something that you yourself describe as "not a good practice", then you should change it.
I would rename your attribute to not have the same name as the class. This will make your code more portable. If you have to move to yet another compiler in the future, you won't run in to this problem again then.
I was reading the Qt coding conventions docs and came upon the following paragraph:
Anything that has a constructor or needs to run code to be initialized cannot be used as global object in library code, since it is undefined when that constructor/code will be run (on first usage, on library load, before main() or not at all). Even if the execution time of the initializer is defined for shared libraries, you’ll get into trouble when moving that code in a plugin or if the library is compiled statically.
I know what the theory says, but I don't understand the "not at all" part. Sometimes I use non-POD global const statics (e.g: QString) and it never occured to me that they might not be initialized... Is this specific to shared objects / DLLs? Does this happen for broken compilers only?
What do you think about this rule?
The "not at all" part simply says that the C++ standard is silent about this issue. It doesn't know about shared libraries and thus doesn't says anything about the interaction of certain C++ features with these.
In practice, I have seen global non-POD static globals used on Windows, OSX, and many versions of Linux and other Unices, both in GUI and command line programs, as plugins and as standalone applications. At least one project (which used non-POD static globals) had versions for the full set of all combinations of these. The only problem I have ever seen was that some very old GCC version generated code that called the dtors of such objects in dynamic libraries when the executable stopped, not when the library was unloaded. Of course, that was fatal (the library code was called when the library was already gone), but that has been almost a decade ago.
But of course, this still doesn't guarantee anything.
If the static object is defined in an object that does not get referenced, the linker can prune the object completely, including the static initializer code. It will do so regularly for libs (that's how the libc does not get completely linked in when using parts of it under gnu, e.g.).
Interestingly, I don't think this is specific to libraries. It can probably happen for objects even in the main build.
I see no problem with having global objects with constructors.
They should just not have any dependency on other global objects in their constructor (or destructor).
But if they do have dependencies then the dependent object must either by in the same compilation unit or be lazily evaluated so you can force it to be evaluated before you use it.
The code in the constructor should also not be dependent on when (this is related to dependencies but not quite the same) it is executed, But you are safe to assume that it will get constructed at the very least (just before a method is called) and C++ guarantees the destruction order is the reverse of instantiation.
Its not so difficult to stick to these rules.
I don't think static objects constructors can be elided. There is probably a confusion with the fact that a static library is often just a bunch of objects which are token in the executable if they are referenced. Some static objects are designed so that they aren't referenced outside their containing object, and so the object file is put in the executable only if there is another dependency on them. This is not the case in some patterns (using a static object which register itself for instance).
C++ doesn't define the order that static initializers execute for objects in different compilations units (the ordering is well defined within a compilation unit).
Consider the situation where you have 2 static objects A and B defined in different compilation units. Let's say that object B actually uses object A in it's initialization.
In this scenario it's possible that B will be initialized first and make a call against an uninitialized A object. This might be one thing that is meant by "not at all" - an object is being used when it hasn't had an opportunity to initialize it self first (even if it might be initialized later).
I suppose that dynamic linking might add complexities that I haven't thought of that cuase an object to never be initialized. Either way, the bottom line is that static initializatino introduces enough potential issues that it should be avoided where possible and very carefully handled where you have to use it.