====== A quick one ====== Just a quick something to keep this site alive. These two issues were nothing that got //me// fuming angry, but my boss was not amused when I was blindsided by these two issues in a production environment. ===== One: bash ''tee'' and return values ===== There is this nice UNIX tool named `tee` that writes its standard input to a file without actually consuming it. It is very useful in scripts where you want to print the proceedings to screen while at the same time logging them somewhere: someCommand | tee -a logfile.txt # '-a' to append instead of overwriting It gets ugly, though, when you add this kind of logging to a script retroactively, //and fail to realize that the next step in the original script was to check if ''someCommand'' was successful//: someCommand | tee -a logfile.txt if [ $? != 0 ]; then … Congratulations: Because ''$?'' returns the exit code of the //last// command executed, you just checked whether ''tee'' succeeded (e.g., in logging ''someCommand''’s failure). Luckily, bash offers a way out: The array ''PIPESTATUS'' carries the individual exit codes of all commands in the pipe chain. someCommand | tee -a logfile.txt if [ {$PIPESTATUS[0]} != 0 ]; then … ===== Two: ''va_arg'' and C++ references don’t mix. ===== Consider: #include #include using namespace std; void foo( std::string & parmN, ... ) { va_list ap; va_start( ap, parmN ); int i = va_arg( ap, int ); va_end( ap ); } int main() { std::string broken; foo( broken, 42 ); return 0; } //The variable ''i'' will most likely not be set to 42.// The reason is that most implementations of ''va_arg'' will take the address of ''parmN'' using the address operator ''&''. For a C++ reference, like in this case, this will yield the address //of the referenced variable//. You will not get the address of ''parmN'', but the address of ''broken'', and whatever you pull out of ''va_arg'' will not be what you expected. ---- These two [[http://en.wikipedia.org/wiki/Lobo_%28DC_Comics%29 | bastiches]] caused me some hurt. Be warned.