Advertising

Reasons against advising beginners to use Dev-C++ in 2011

You may be tempted to recommend Dev-C++ to a beginner, or you may be a beginner tempted to use it.

Stop.

It's 2011. Dev-C++ is not in development since 2005. Its latest version is a beta, and as you code, its beta status will be felt. Here is a short list of why a beginner should not use Dev-C++, and why he will not miss it after no longer being a beginner. Of course, this is also a list of reasons why competent and advanced coders should not use it. (Update March 28 2012: Here's an additional opinion from way back in 2008.) (in subjective order of importance)

1. Horrible auto-indentation A beginner is still learning. A beginner will not know how to format code properly. Minimum of proper code formatting will have to be explained up to 10 times before the beginner will start properly formatting the code.

Having poor auto-indenation means someone will have to constantly review beginner's code and correct its formatting. Having poor auto-indentation will slow down an advanced developer since he will have to fight the poor built in capabilities constantly.

Disabled indentation would be better than what Dev-C++ has.

2. Bad auto-completion Dev-C++ can't recognize many language constructs. Sometimes it will show senseless tooltips. It especially becomes noticeable once you try another IDE.

3. "Unhandled exception" Dev-C++ is developed in Delphi, and what would crash other programs, sometimes allows Dev-C++ to live. But, it still throws warnings at weirdest times.

4. Debugger UI is a joke Sometimes it works, sometimes it doesn't. Half the time you need to open debugger console and manually talk with GDB to get anything done (even things like backtrace).

5. Horrible dependency tracking in the build system While only important if you are a large project developer, note that by default, Dev-C++ will be horrible at tracking which headers are important for a particular implementation file (by which I mean .c and .cpp files); it won't track it at all. If you change a header that you use in many places, a full rebuild is in order. If you turn on full dependency tracking, you'll face somewhat reliable, but abysmally slow dependency tracking.

What's wrong with this? You could be changing a class declaration in a header, but most implementation files that depend on this header will not be rebuilt, causing the program to crash at weirdest places, or work incorrectly, until full rebuild is performed.

6. Files used not by path, but by filename Again important for projects. This means you cannot have two files of same name in the same project, placed in different directories.

7. Single-platform When you can have such excellent IDEs such as Code::Blocks, or to a lesser extent CodeLite, and use same project files on multiple platforms, why restrict yourself to an IDE that appreciates only Windows?

///////////////////////// All of the above mean that an experienced developer will needlessly suffer, and a beginner will learn incorrectly, or be wondering what went wrong. While Dev-C++ could have become an excellent IDE over the years (which is why back in 2005 and 2006 I extensively used it), its development has stopped.

You should not be using deprecated beta software. You should not be recommending software that might teach incorrect practices to a beginner. You should not lose your precious time on wrestling with the IDE just to retain some semblance of order in code.

Recommended C++ IDEs: - Xcode - for Mac OS X developers; you don't need to switch to Windows to learn or to develop quality software - Code::Blocks - perfect for developing Windows and cross platform code - CodeLite - while my personal impressions of CL are not as good as of C::B, still a nice IDE - Visual C++ Express - 2005, 2008 and 2010 are quite nice free offerings from Microsoft; I don't personally like them, but they're reasonably good if you are into MS software


rest of the post
About me

Testing for presence of Apple platform in C/C++/ObjC code

Are we running on an Apple platform?

#ifdef __APPLE__
#endif

Prerequisite for other tests

#ifdef __APPLE__
// let Apple define 
// various TARGET_OS_ 
// constants
#include  
#else
// not on Apple platform
#define TARGET_OS_MAC 0
#define TARGET_OS_IPHONE 0
#endif

Are we running on Mac OS X?

#if TARGET_OS_MAC && !TARGET_OS_IPHONE
….
#endif

Are we running on an iOS device?

#if TARGET_OS_IPHONE
….
#endif

// updated on Oct13 2010, previous method was flawed. sorry everyone!


rest of the post

iPhone development: Bits/c++config.h: No such file or directory

Developing for iPhone with some C++ code? Suddenly getting this error after installing a beta SDK?

/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.2.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h:65:0 Bits/c++config.h: No such file or directory in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.2.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h

Note the bolded folder. Change into it and make a symlink from arm-apple-darwin9 to arm-apple-darwin10. Please note that Apple has fixed this already at one upgrade of beta SDK (I had this error before too, but I still didn't get 4.0 beta 2 so I didn't check) so it's reasonable to assume they will do this again.

cd Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.2.sdk/usr/include/c++/4.2.1/
ln -s arm-apple-darwin9 arm-apple-darwin10

PS I don't think posting this violates any NDA. Especially since origin for this solution is also public.


rest of the post

Fixing "warning: missing sentinel in function call"

I got it for the folowing line:

execl("/bin/sh", "sh", "-c", sessioncommand.c_str(), 0);

Quite easy to fix:

execl("/bin/sh", "sh", "-c", sessioncommand.c_str(), (char*)0);

-----------------------------------------

Alright. Since I'm getting "lots" of hits on this, let's see if we can improve this post. (June 28th 2010, more examples added July 22nd 2010, style but not content updated April 19 2014)

Generally, you're missing a sentinel if you don't add a "NULL" in C/C++, or a "nil" in Objective-C. In above example in C, I presume the compiler did not notice the zero (a valid sentinel) and threw a warning. That's what this post was mostly about.

However, it could also happen if you really did forget to add the sentinel. What is the purpose of this "sentinel"? When iterating through a varlist**, the function needs to know where to stop. In printf() and scanf(), the format string specifies this number of arguments. Functions could also accept the number of arguments as one of the arguments. Third option is this -- specifying a sentinel, such as NULL or nil, as something that will stop further iteration.

Examples of sentinels in C:

execl("/bin/sh", "sh", "-c", sessioncommand.c_str(), NULL);


and in Objective-C:

NSArray *names = [NSArray arrayWithObjects: @"Ivan", @"Ana", @"Marko", @"Petar", nil];

** Iterating through a varlist - which is how you iterate through arguments in variadic functions, those with variable number of arguments


rest of the post

close() of listening socket from another thread

Just a warning.

Calling close() on listening socket in another thread will NOT prevent another connection from being made. Instead, you must call shutdown(). This should abort existing select() calls (probably accept() too, but I didn't try).

Guess how I found out :-)


rest of the post

Great new GCC option - Effective-C++ Warnings

Did you know about -Weffc++ in GCC? Neither did I, until I upgraded to new Code::Blocks from Jens' unofficial Debian repository for Code::Blocks.

Here's a few sample warnings, with sample lines and commentary:

  • /home/ivucica/Development/project/src/types.h|12|warning: ‘operator=’ should return a reference to ‘*this’|
Sample:
Position &operator=(const Position& other) { x=other.x; y=other.y; z=other.z; return *this;}


What's the big deal here? By leaving out the ampersand in this operator overloading, I accidentally returned a copy of entire Position class. (On the other hand, I had no reason to actually overload this operator so perhaps real fix is to erase entire line. Still...)

  • /home/ivucica/Development/project/src/mat.h|10|warning: ‘class Mat’ has pointer data members|
    /home/ivucica/Development/project/src/mat.h|10|warning: but does not override ‘Mat(const Mat&)’|
    /home/ivucica/Development/project/src/mat.h|10|warning: or ‘operator=(const Mat&)’|
No sample needed.

What's the problem here? Well, we have a Mat class containing pointer. So what happens when someone does this: Mat x = y; or this: Mat x(y);? We have another instance of a class with copies of all the data, except the data pointed to by the pointer. Instead the pointer itself gets copied.

So if we keep a C-style string in there, we're not really copying the string ... we're copying the pointer to it, and modifying the string in the new instance still modifies the string in the original ocpy.

While not applicable everywhere, still a good and useful warning.

  • /home/ivucica/Development/project/src/obj.h||In constructor ‘Obj::Obj()’:|
    /home/ivucica/Development/project/src/obj.h|15|warning: ‘Obj::m_radius’ should be initialized in the member initialization list|

Simple. Instead of initializing (or forgetting to initialize, or intentionally doing so) a variable in the constructor:
Obj() {m_classname="Obj"; m_usecount = 0; }
why not do it in a "safe" and readable way (and perhaps more optimal?)
Obj() : m_classname("Obj"), m_usecount(0) { }


While these warnings are certainly not the Universal Elixir to cure all your troubles, they will certainly prove useful in furthering your 1337 skills.


rest of the post