Shaving some time
I was talking to a colleague the other day and got into a discussion regarding some ways of coding c++, such as whether to use division or bit shifting — almost all modern compilers can optimize this so it’s basically just a matter of what looks best. At the same time, we got into a minor discussion regarding references and pointers in c++. I made a small test and found some rather amusing results, which is quite obvious once you think about it, but still very scary considering how common it is to use the pointer construct:
// Compile using g++ -lrt -o lala lala.cpp #include <iostream> #include <time.h> int* lala_ptr() { int *y = new int; *y = 5; return y; } int& lala_ref() { int x =5; int &y = x; return y; } timespec diff(timespec start, timespec end) { timespec temp; if ((end.tv_nsec-start.tv_nsec)<0) { temp.tv_sec = end.tv_sec-start.tv_sec-1; temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; } else { temp.tv_sec = end.tv_sec-start.tv_sec; temp.tv_nsec = end.tv_nsec-start.tv_nsec; } return temp; } int main(int argc, char **argv) { timespec time1, time2, time3; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); for (unsigned int i=0;i<(unsigned int)-1;i++) { int &z = lala_ref(); } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); for (unsigned int i=0;i<(unsigned int)-1;i++) { int *z = lala_ptr(); delete z; } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time3); std::cout << "Reference diff(" << time1.tv_sec << ":" << time1.tv_nsec << ", " << time2.tv_sec << ":" << time2.tv_nsec << ") = " << diff(time1, time2).tv_sec << ":" << diff(time1, time2).tv_nsec << std::endl; std::cout << "Pointer diff(" << time2.tv_sec << ":" << time2.tv_nsec << ", " << time3.tv_sec << ":" << time3.tv_nsec << ") = " << diff(time2, time3).tv_sec << ":" << diff(time2, time3).tv_nsec << std::endl; }
Below is a sample of the output generated by the test code above:
oan@laptop4:~/Projects/test$ ./testRefVsPointer Reference diff(0:3869272, 25:234466470) = 25:230597198 Pointer diff(25:234466470, 299:547382527) = 274:312916057
So, the question for you all, can you figure out what's wrong? 😉
Unit testing and stubbing singletons
I got a bit curious about stubbing Singletons for testing during the weekend as well. We often find ourselves needing to test large codebases at work, and in the current project I’m in, we do complete end to end signal flow tests, but people are finally realizing that this will simply not do. For this reason, we’re doing a lot of work to try to split the entire project up into manageable chunks. One of the main problems has been the incessant use of singletons. A simply half-way-there to doing full out interfaces is to simply make all public function calls virtual and then create a stub class of the singleton saving the message or whatever passed on, into a variable which can be grabbed and tested from the actual unit test.
A sample of the general idea below:
#includeclass A { public: static A *instance() { std::cout << "A::instance()" << std::endl; if (!s_instance) s_instance = new A; return s_instance; }; A() { std::cout << "A::A()" << std::endl; }; // Virtual makes the difference virtual void send(int i) { std::cout << "A::send()" << std::endl; // Blah blah, send i or something }; static A *s_instance; private: }; class stub_A: public A { public: static stub_A *instance() { std::cout << "stub_A::instance()" << std::endl; if (!s_instance) { s_instance = new stub_A; A::s_instance = s_instance; } return s_instance; }; stub_A() { std::cout << "stub_A::stub_A()" << std::endl; }; void send(int i) { std::cout << "stub_A::send()" << std::endl; y = i; }; int getMessage() { return y; }; private: int y; static stub_A *s_instance; }; A *A::s_instance = 0; stub_A *stub_A::s_instance = 0; int main(int argc, char **argv) { stub_A::instance()->send(5); std::cout << "stub_A::instance()->getMessage() == " << stub_A::instance()->getMessage() << std::endl; A::instance()->send(7); std::cout << "stub_A::instance()->getMessage() == " << stub_A::instance()->getMessage() << std::endl; }
Build components
Filed under: Configuration Management, Development
After a weekend of work, I finally got myself a build component that I’m semi-pleased with, for C and C++ projects, using Subversion. Most likely works for any other lower level programming language as well.
First off, structure. Each component is it’s own BTT(Branches, Tags, Trunk)-root, residing in a Project_Modules directory in subversion. Each component contains an inc, src, test and a stubs directory. Rationale for the BTT-root is that, with a separate BTT-root for each component we can raise the version of each separate component without having to raise it for the entire project.
The Project directory resides on the same level as Project_Modules, and is empty, only containing the subversion property externals pointing to the trunks of the Components in Project_Modules. Rationale for this is to have a simple place to checkout the entire project. It’s a bit dangerous when working with branches, and requires a little bit extra care so one doesnt write into the trunk out of mistake. Possibly block everyone but a specific user to write in the trunks and have that CM person do all the branching/merging. It is time consuming however.
It looks something like this:
- Project_Modules
- Component1
- inc
- src
- test
- stubs
- Component2
- inc
- src
- test
- stubs
- Project
Inc directory is the public interface of the component towards the other components. Src directory contains the actual code of the component. Test contains unit tests (personally, i create a new directory for each new unit test file). Stubs contains the stubs of my own component. Ie, Component1/stubs will contain stubs for the functions in Component1. Rationale being that 95% of the time, we want to stub another component in the same way, instead of keeping stubs of a component in 10 different components, we keep it in one place.
Switching GNU toolchains in eclipse — the easy way
This is a method of switching to a different toolchain that I found in eclipse. Basically, my goal was to get eclipse to use a secondary toolchain. Primarily in my first step, I tried making eclipse use a crosscompiling gnu toolchain.
Doing this the “right” way seems to entail writing plugins eclipse, and to write lots of XML configurations and so forth. Not having the luxury of infinite time and money (yet wanting a managed build), but rather being result driven, I finally managed to solve it partially with a hack.
My secondary goal now is to make the build work with a completely “non-gnu toolchain” (renesas sh compiler), I will try to hack together this in the upcoming days. I’ll get back to this topic again, once I know if it works or not. In the meantime, this is how I got it to compile with “non-standard” toolchain, and “standard” cygwin toolchain at the same time.
- Install the toolchain somewhere.
- Setup your PATH with the /bin/ directory in it.
- Start -> Control Panel -> System.
- Enter the Advanced tab.
- Click Environment Variables.
- Find the PATH variable in System variables.
- Edit and add ;c:pathtoyourtoolchain at the end of it.
- OK
- OK
- Create a new Build Configuration (Target for example).
- Right click the project in the Project Explorer.
- Build Configurations -> Manage…
- New…
- Write name “Target” and a description.
- Copy settings from another target that might contain decent default values.
- Ok
- Ok
- Edit the Settings for the “Target” Build Configuration.
- Right click the project in the Project Explorer.
- Choose Properties.
- Go to C/C++ Build -> Settings.
- Choose the right Configuration at the top (Target in our case).
- For each heading in Tool Settings (GCC Assembler, Cygwin C Compiler, Cygwin C Linker)
- Click the heading.
- Edit the Command field (for example, instead of using gcc, you might be using arm-elf-gcc or m68k-uclinux-gcc).
- Apply.
- OK.
- Try to build the new “Target” Build.
Moving interface from Enterprise Architect to C include file
After writing this, i realized the output after this is almost 100% the same as I got from exporting the original class as a C header from Enterprise Architect, still putting this out there as it’s a nice regex. Cut n paste each function line from EA to the header file. format will be a bit screwed up, for example:
functionname(varname: vartype, varname2: vartype2): void
Begin with moving trailing return type to beginning:
:%s/^\(.*)\): \(\w\+\)$/\2 \1;/g
Get all varnames and vartypes into correct positions:
:%s/\(\w\+\): \(\w\+\)/\2 \1/g
All function declarations should now be fixed.
Qt presentation tomorrow
So, I’m holding a brief Qt presentation on a demo i made a few weeks back. It’s pretty, and got a ton of stylesheets on it. Going down tomorrow at work. Hopefully people will be a little bit interested at least. It’s not that often I dare get my ass up there behind a podium, or speak up at all for that matter.
To be honest, I don’t know why really, I just hate being in front of people talking and possibly saying anything that might be wrong. Of course, there’s a reason why I’m doing the presentation, and not someone else. I’m the only one with any substantial experience at all of this subject, so why not basically.
Also, I’m feeling horribly stressed as of late. I started on a project last week, and it’s getting to me. Need to take a minute, sit down, and calm down.
Added Miscellany section
A miscellany section has been added, containing lots of junk and other stuff that I am no longer developing, or that I have written previously. If anyone is interested in using any of the code, they are welcome to. This could mainly be looked upon as a junkyard of more or less useful scrap.
Miscellany update
Two new scripts added to the miscellany section, just for fun. I will add more later on, which may be a little bit more useful to you. Also, as some of you may have noticed, I have been very quiet for a long time. There are things happening that will take some time more to finish, that will hopefully make people a little bit happy in the future. As some has also noticed, there is the new banner on top of the page which points to a site I am partially related to working on. Hopefully, this will not cause too much of a problem for people:).