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.