Posts

Showing posts with the label programming

CMake configuration for reproducible builds of C++ projects with gcc/Linux

This is a quick guide for configuring CMake such that every rebuild of the same C++ code generates bit-by-bit identical binaries. This is useful in verifying if a given binary is indeed generated from the given sources and comes in handy for configuration control. This article is not a detailed documentation on the reasons or mechanisms that cause binaries to differ from build to build nor the rationale behind the countermeasures explained in great detail. That information is already covered elsewhere and a few helpful links are provided in the end. This post is made because all of this information was not available in one place. In general, the same C++ code should generate the same executable (or library) every time it is compiled using the same build system on the same platform. But in practice, several factors cause the final binaries to differ. There are a few things developers need to take care of to avoid these: Eliminate differences due to build path. target_compile_options(...

Qt - Enabling qDebug messages and Qt Creator

I have been struggling for the past two hours to get qDebug() messages from my Qt 5 application to show up on the 'Application output' pane in Qt Creator IDE on Linux. Finally I found a solution, thanks to a user on Qt IRC channel. To enable log messages in Qt, do the following: Edit ~/.config/QtProject/qtlogging.ini and make sure it has: [Rules] *.debug=true qt.*.debug=false With this, I was getting the messages when I run the application from a terminal. But Qt Creator was not showing the qDebug() messages. To have the messages displayed in Qt Creator, do the following: Qt creator > Tools > Options > Kits, select your kit, find Environment, click change and add: QT_ASSUME_STDERR_HAS_CONSOLE=1 This fixed the problem for me. I thought I should document the full process here as Google wasn't getting me good leads. My environment: Fedora 29 Linux x86-64 Qt 5.11.3 Qt Creator v4.7.2 References: https://bugzilla.redhat.com/show_bug.cgi?id=12272...

Fun with arrays in C & C++ - Part2

In Part-1 , we saw a couple of examples on array indexing and pointer arithmetic. Lets dive a little deeper in to array types . Arrays & pointers An array is a series of contiguous values in memory and the array name gives us a handle to this list. In C and C++, a pointer refers to (or points to ) another object in memory. Since arrays are guaranteed to be contiguous, if we have a pointer to the first element in the array, we can access the whole array (as long as we know how big it is) Assigning the address of the first element to a pointer: int a[100]; int *p = a; //p  now points to a[0] Here p is a pointer to int and we are simply using the array name for assignment. The array name is said to freely decay to a pointer to the object's type . i.e. if a is an array of objects of type T, then it can be seamlessly converted to a pointer to T (i.e. to a T* ). This is what happens when you pass an array's name to a function that takes a poin...

Fun with arrays in C & C++ - Part1

I was explaining some stuff about arrays and pointers to a colleague and thought I should do a post about this. So here goes.. Declare 'a' as an array of 100 int objects: int a[100]; Set the 10th element to the value 1000: a[9] = 1000; The square brackets we used in the above expression is called the subscript operator . We use the index value 9 to access the 10th element because arrays in C and C++ are indexed from 0. So far so good. Now, what if that statement is slightly modified to: 9[a] = 1000; If that looks weird and possibly wrong to you, be assured that it is perfectly legal C/C++ code! Moreover, it is identical to the statement: a[9] = 1000. If this is news to you, then you need to read on.. The subscript operator The subscript operator works like this: The expression E1[E2] is equivalent to *(E1+E2) ; where E1 and E2 are expressions themselves. i.e. E1[E2] = *(E1+E2) = *(E2+E1) = E2[E1] (keep in mind that we've no...

rpmbundle - Copy RPMs for offline installation

Installing Fedora (and most other free distros) on computers without a fast (and economical) Internet connection is a bit painful since most of the popular multimedia file formats aren't supported out of the box . Being a free distribution, Fedora only supports and includes free and open source software. Support for all the other patent encumbered formats are available from RPMFusion repository. However, you'll need a fast (and reasonably cheap) Internet connection to download several megabytes worth of RPM files from these repositories. I present here the steps and a small utility program for copying RPM files from a PC with Internet connection for offline installation at other computers. This can be used to update existing installations or to install new software on stand-alone PCs. Step 1 - Download RPMs The simplest way to harvest RPMs is to enable YUM's cache on the source machine. This way, everything YUM fetches on the machine will be available in...

A caveat on using %u with scanf for reading positive integers

Do you use scanf() class of functions ? Do you use the %u conversion specifier to read positive integer values? Do you use the return value of scanf() as a confirmation of successful operation? If you do, then read on.. The task Parse a string (e.g. "42") (or a field within a string) to read a positive decimal integer value and validate it by confirming that the string indeed is a positive integer (and not things like "abcd", "-42"). Use the C programming language . The sscanf method The scanf class of functions (scanf/sscanf/fscanf) supports several conversions for reading different types of values - integers, floats, strings etc. The conversions to be done on the input are specified by means of a format string argument. A conversion specification typically consists of the  '%' character followed by a character specifying the conversion to be performed. For example, "%d" is for reading 'int' values, "%u...

The woes of structure packing - #pragma pack

We were developing an application on Red Hat Enterprise Linux 5.3 that, among other things, needed to use a PCI interface card for acquiring IRIG-B time codes. The Qt 4.5 based application was first developed without this capability, and later the device driver API was integrated to it. The API had a header file with a class declaration and a corresponding source file containing definitions of the class functions. Integrating the API involved adding these two files to the list of the project's source files and making calls to the API functions. This integration caused the application to abruptly crash after receiving SIGABRT signal. The reason reported was along the lines of: “ *** glibc detected *** application_name: malloc(): memory corruption: 0x092a51c8 *** ”. Being a memory error, we used Valgrind to locate any memory access violations. We found that the crash always happened at a single statement that dynamically allocated memory using operator new. The statement ...

The Frog in the Well and the Assignment Operator

One or two years back, I attended an interview for a very popular multinational company. I was happy with the job I had and attended the walk-in interview just to see what the industry is looking for. Those days, I was quite comfortable with C++ programming and considered myself really good at it. I hadn't applied for the interview. Some HR firm had tracked me down via someone else's referral and had asked me to attend the walk-in. So, I walked in without even a resume. The guys at the interview were quite surprised but were kind enough to let me write down my resume summary on a sheet of paper! Anyway, I had two rounds of technical interviews, and I did pretty well on those. The first interviewer asked me how I rated myself on C++ skills. I confidentially said "about 8". He was shocked and said "I guess even Stroustrup considers himself a 7 or so". All I could manage to say to that was "perhaps he knows a lot that he realises that he has much m...

Life Expectancy

Image
I booked a train ticket for my mother using IRCTC . I was quite (pleasantly) surprised to find the age printed in 3 digits in the Electronic Reservation Slip : I find the zero-padding a bit geeky. The Right Way, IMO, would've been just printing it in 2 or 3 digits depending on the value. ------ It'd be utterly ungrateful if I didn't mention the nice tool I used to grab the above screenshot. It's called Shutter . It's one amazing tool (despite being GNOME!) for quickly creating screenshots. Almost everything you need to do with the grabbed image (adding arrows and text, masking sensitive info etc. etc.) can be done within the same application! Isn't that wonderful? Just that the UI is not all that intuitive :-( PS: A quick piece of info you already knew: the following C code prints the value with zero padding: printf("%03d\n", 54); With cout/C++, the same effect can be achieved with the ugly: cout << setfill('0') <...