Posts for 2016 May
Deobfuscate your bash
Post by Nico Brailovsky @ 2016-05-31 | Permalink | Leave a comment
Who hasn't written some read-only magical Bash voodoo, only to find you need to decrypt your own creation later on? Luckily, Explain Shell can help with that. Here's an example from my .bash_history file:
for fn in *; do echo cat $fn | sed "s|' '$URL'||g" | sed "s|curl -X POST -d '||g" ; done
And Explain Shell's explanation: it's no substitute for knowing Bash but it sure helps.
Bonus: while reading my bash history file, I realized I accidentally copy&paste a lot of code to my terminals. There are way too many "template
Bonus II: It's a good thing they wrote "shell" in a different color. I was wondering why I had "explains hell" in my bookmarks.
Awesome (and useless) trivia: Ubuntu's first bug
Post by Nico Brailovsky @ 2016-05-26 | Permalink | Leave a comment
I'm still not over the disappointment from my latest Ubuntu install but recently I found a bug which is quite remarkable: https://bugs.launchpad.net/ubuntu/+bug/1
Yes, Ubuntu's #1 bug, reported by Shuttleworth himself, is "Microsoft too big". I'm not too sure I agree with the bug's resolution.
KSnapshot is getting smarter
Post by Nico Brailovsky @ 2016-05-24 | Permalink | Leave a comment
I just noticed KSnapshot is smart. Too smart. If you save a snapshot to a folder with a bunch of files like "Snapshot_N_foo" it'll name the next one "Snapshot_N+1_foo". That already makes my computer smarter than some humans!
I can't believe this works!
Post by Nico Brailovsky @ 2016-05-19 | Permalink | Leave a comment
Are you bored? Try pasting this, as is, in a cpp file:
// What is going on here??/
Is this even legal C++??/
Yes, it is!
NB: You may have to use -trigraphs to compile this. Try it out! You can use this command:
echo -e "// What is going on here??/Is this legal C++?" | g++ -E -c -trigraphs -
With some luck, this won't be legal C++ anymore after C++ 17 deprecates trigraphs.
Some sane advice from Firefox's console
Post by Nico Brailovsky @ 2016-05-17 | Permalink | Leave a comment
Tinkering with Firefox' JS console I had to copypaste some stuff. I got a really nice surprise when it wouldn't let me:
Scam Warning: Take care when pasting things you don't understand. This could allow attackers to steal your identity or take control of your computer.
That's some really good advice coming from your browser's console.
Quickly sharing files in Linux via HTTP
Post by Nico Brailovsky @ 2016-05-12 | Permalink | Leave a comment
Isn't it awful when you have to share a file too big for email and don't know how? You'd think by 2016 we'd have that figured out. Actually we do, many times over. Just pick a standard that works for you!
If you don't want to read many pages on file transfer standards (Samba? What's that?) you can try this little snippet:
python -m SimpleHTTPServer $PORT
This will create an http server sharing the current directory. HTTP, luckily, is one of those things that tend to work everywhere, always.
Bonus: some other ways of doing the same thing at https://gist.github.com/willurd/5720255
Initialization oddities: Aggregate initialization
Post by Nico Brailovsky @ 2016-05-10 | Permalink | Leave a comment
Do you know the quickest way to create a constructor that initializes the elements in this struct?
#include
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};