Gotcha (programming)
From Wikipedia, the free encyclopedia
In programming, a gotcha is a feature of a system, a program or a programming language that works in the way it is documented but is counter-intuitive and almost invites mistakes because it is both enticingly easy to invoke and completely unexpected and/or unreasonable in its outcome.
Contents |
[edit] Gotchas in the C programing language
| This section does not cite any references or sources. (December 2007) Please help improve this section by adding citations to reliable sources. Unverifiable material may be challenged and removed. |
[edit] Equality operator
The classic gotcha in C is the fact that
if (a=b) code;
is syntactically valid and sometimes even correct. It puts the value of b into a and then executes code if a is non-zero. What the programmer probably meant was
if (a==b) code;
which executes code if a and b are equal. To avoid this gotcha, it is recommended to keep the constants in the left side of the comparison, i.e. 42 == meaning_of_life rather than meaning_of_life == 42.
[edit] Function calls
Example from computer languages such as C:
#include<stdio.h> foo() { printf("42"); } #if 0 /* This function declaration is INCORRECT. There have to be parentheses. * If you want to see the compiler error message, please remove the whole #if and #endif lines */ bar { } #endif main() { foo; /* does NOTHING, it just gets the address of the function foo and does nothing with it. */ foo(); /* prints 42 */ }
[edit] Gotchas in the C++ programing language
[edit] Initializer lists
In C++, it is the order of the class inheritance and of the member variables that determine the initialization order, not the order of an initializer list:
#include <iostream> class CSomeClass { public: CSomeClass(int n) { std::cout << "CSomeClass constructor with value "; std::cout << n << std::endl; } }; class CSomeOtherClass { public: CSomeOtherClass() //In this example, despite the list order, : obj2(2), obj1(1) //obj1 will be initialized before obj2. { //Do nothing. } private: CSomeClass obj1; CSomeClass obj2; }; int main(void) { CSomeOtherClass obj; return 0; }
[edit] Gotchas in Ruby programing language
[edit] Iterating Range
Ruby has a data type called Range; an object of this type constitutes a set of everything between the start and end of the range (including or not including the limits, depending on additional conditions). Since Range is a subclass of Enumerable, one would intuitively expect that iterating a valid Range object will give you every single object in that set, from start to end. This expectation turns out to be incorrect:
irb(main):001:0> (1..3).each { |i| puts i } 1 2 3 => 1..3 irb(main):002:0> (3..1).each { |i| puts i } => 3..1 irb(main):003:0>
[edit] Returns from the block
return statement returns from the context it was defined in, not from the context it's currently executed in. For example:
def boo() transaction do ... return if(something) ... end end
One might expect that return would allow the transaction to be properly closed, but unfortunately that's not the case -- the code in transaction() taking care of that will never be executed if something=true.

