Initialization oddities: Aggregate initialization

Do you know the quickest way to create a constructor that initializes the elements in this struct?

#include <string>
struct MyStruct {
    int x;
    std::string y;
    const char *z;

If you answered “by typing really fast”, you may be interested in knowing that the fastest way to create this constructor is to not write it at all!

MyStruct a = {42, "Hello", "World"};

Yes, the line above works and it’s perfectly legal C++. It’s event C++ 98! This language feature is called aggregate initialization and it says the compiler should be smart enough to initialize MyStruct using each value successively. Of course C++11 has made this syntax somewhat simpler and a lot more uniform:

MyStruct a{42, "Hello", "World"};

There are some caveats when using this initialization, namely that the initialized type must be an aggregate. An aggregate, in standard lingo, is a type that has some restrictions. No virtuals, no privates, etc. You can say it’s a POD and in most cases you’d be right.

Now, is this also legal?

MyStruct a = {42, "Hello"};

You’d be tempted to say that’s a syntax error. It’s not, now z will just be default-initialized. What about this, then?

MyStruct a = {42, "Hello", "World", "Extra!"};

According to the standard, that’s an error. Or… is it? Let’s try out this example:

struct A {
    int x;

struct B {
    A a;
    std::string y;

struct C {
    B b;
    const char *z;

C o = {42, "Hello", "World"};

Yes. Believe it or not, the object o will now contain three members: o.b.a.x, o.b.y and o.z. All three will be properly initialized with their respective value.

Aggregate initializations should, according to the standard, be smart enough to initialize aggregate objects and use any “spill over” to continue initializing other values/aggregate objects recursively.

Bonus I:

Aggregate initialization is also what makes this idiom valid:

char x[] = {1, 2, 3}

In this case, x will be of length 3 because that’s the length of its aggregate initializer.

Bonus II:

I’m sure anyone trying to get up to date with C++11 will have played around with variadic templates. One of the first exercises I’d recommend for this would be a compile-time list of different types. Knowing about aggregate initializations now, how would you write a constructor for this type?

template <typename H, typename... T>
struct Multilist<H, T...> {
    H x;
    Multilist<T...> next;

Multilist<int, string, float> foo{42, "XXX", 1.23};

Code and Google translate: awesomeness

Some time ago I found out one of my articles was translated to another language (yay for that, woo for not letting me know about it). To understand what my own article said, I had to use Google translate on the site. Guess what? c++ and Google translate can produce hilarious results:
# The include "throw.h" the extern "the C" {void seppuku () {throw statement the Exception () ; }}
Another one I liked:
the struct the Exception {}; # ifdef __cplusplus the extern "the C" {# endif void seppuku (); # Ifdef __cplusplus} # endif
Now you know it. Next time you’re looking at some incomprehensible c++ code, run it through Google translate. It may improve it.


Lately I’ve been toying around with gcc to learn a bit better how its optimization phases work. Understanding Gimple, the intermediate representation used by gcc, is a useful skill for this. Of course actually *understanding* it is quite an ambitious and daunting task, so it may be a bit more useful to skim through it.

Turns out that using -fdump-tree-all and -fdump-rtl-all its possible to get a lot of interesting information on the phases the compiler follows to get your code optimized, but the sheer amount of information produced makes it rather hard to make sense out of it. During the next few posts (weeks? months? probably until I satisfy my curiosity about gcc) I will be investigating a little bit the output of the -fdump options in gcc, to see what can be learned from it.



Some new set operations in C++11 stl

The std header has a few cool additions that make life easier in C++11:

void f() {
  vector<int> v = {1, 2, 3, 4, 5, 60, 70, 80, 90};

  auto less_than_10 = [](int x){ return x < 10; };
  if (all_of(v.begin(), v.end(), less_than_10)) {
    cout << "Yay!";

Besides all_of, in you can also find any_of and none_of.

Bonus: do you find that initializer list hideous? Just use std::iota, from stl too:

vector<int> v(100, 0);
iota(v.begin(), v.end(), 0);

Goto hell

Small and funny easter egg I found by accident today: stop using “adb shell” to access your device. You’re wasting precious keystrokes. Instead, you should be using “adb hell”. Yes, ‘adb hell’ works just as well as ‘adb shell’ – but it’s even more awesome. Go and try it!

PSA: OEM unlocks may result in wiped filesystems

So, I bricked my tablet. Turns out the bootloader couldn’t mount /data: after doing an oem unlock thingy, /data gets wiped and (this is the part the manual I was following didn’t warn me about) no filesys is created.

If this happens, go back to recovery mode, then adb shell and run ‘mount /data’. This will give you an error like “Can’t mount /dev/block/mmcblk0p23”. Write down the /dev/block id and run ‘mke2fs -t ext4 /dev/block/mmcblk0p30’. That should fix it.

In some systems you may be missing If this happens, just look for in the interwebs, then adb push this file into /sbin.

VLCFreemote: no need to leave the couch

I’ve been quite prolific in my Github account recently, if I may say so myself. The latest of my open-source projects which I think is more or less ready to be “released to the world” is VlcFreemote, a remote control for VLC in Android. From its README file:

How many times have you been comfortably watching a movie from the couch only to find out you forgot the subtitles? How about being snugly tucked under a blanket, only to find out you need to brave the cold of winter just to add a new episode of your latest binge-watching series? Yeah, that can easily ruin your day.

Worry no more: with VlcFreemote you can now install a tiny Android app to control your VLC server.


  • Another VLC remote? Why?There are a few VLC remote controls out there. I think this is the only once that’s open source (not 100% sure). It has some nice extra features I haven’t found in other remote controls too: bookmarks, automagic movie-skip (jump forward by a percentage of the file length, much more useful than it sounds!) a compact layout and other small things probably not even worth mentioning. In the future, whenever I get some free time, I’d like to add the ability to start VLC automatically from SSH, a feature I would use a lot and I have seen nowhere else.
  • Why isn’t this in Google play?Mostly cause I’m lazy and cheap. Getting a Google Play account costs 10 dollars or so, and I’m too lazy and too cheap to get one. Want me to upload it to Google Play? Feel free to buy me a beer. If not you can just get the APK from Github, or download the source code and build it yourself.

Don’t exit gdb just to run make!

If you’re more or less successful in your debugging session, it’s quite likely that you’ll have to modify some source code so you can actually fix a bug. And if you’re more or less careful, you might want to validate your changes actually work. We saw some time ago that you don’t need to restart gdb after a recompile because gdb is already smart enough to know that the binary changed.

Turns out you don’t even need to drop from gdb to a shell: just type make (using the parameters you’d usually call make with) and watch gdb take care of building your binary again.

Rebuilding your project like this is not only useful to save time: you can also keep your breakpoints and they should still make sense, assuming you didn’t refactor your code too much.

gdb-tui and the previous-command problem

Raise your hand if you have run gdb in tui (graphical) mode, only to find you can’t refer to the previous command when pressing “up”. I can’t see you but I know this is true for pretty much everyone reading this blog. All three of you.

In the gdb-TUI mode, the arrow keys are used by the active window for scrolling. This means they are not available for readline, the component that takes care of the magic invocations needed to bring back the previous command from the land of the dead. Luckily there are alternative readline keybindings: just try C-p, C-n, C-b and C-f. Takes a while getting used to it but you can finally use gdb-TUI and forget about copy-pasting every gdb command.

Bonus tip: if pressing “up” (or C-p) in gdb doesn’t bring back the previous command, it probably means you don’t have the readline package installed. Go ahead an install it. It’ll change your life.

Android studio and ndk-gdb to debug a native app

I don’t know how good Android Studio support for native apps is nowadays (it changes from week to week!). Up to a few months ago, Gradle, the build system used by AS, had poor support for native development. If you’re having problems, you may find it easier to workaround it completely when it comes to build and debug C/C++ applications.

To debug a native Android application, a binary called gdbserver and its associated gdb.setup must be included in the generated APK file. Including this into the APK can be very painful in Gradle, so here’s a workaround I found:

  1. Build your stuff the way you normally would (I’m assuming you know already how to build a native app, and if you don’t there are guides online that explain it much better than I could).
  2. Deploy your application the way you normally would.
  3. Discover ndk-gdb won’t run. Bang forehead against keyboard a few times.
  4. After losing some hours looking at logs, figure out there’s no gdbserver included in your apk.
  5. Lose some more hours trying to figure out how to include it in your apk using Gradle.
  6. Give up. Bang forehead against keyboard some more.
  7. find the gdbserver and gdb.setup in your build directory.
  8. adb push each of these files to the device.
  9. Using adb shell, move the files you copied to /data/app-lib/com.yourapp/ – you may need to root your device for this.
  10. Profit! ndk-gdb now works.


Edit: remember you may need to chmod +777 your gdbserver.