Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is preprocessor usage less common in languages other than C/C++/ObjC?

I've been a Java and VB.Net programmer for about 4 years and a C# programmer for about 6 months. I've also used a bunch of dynamic languages like Perl, Python, PHP, and JavaScript.

I've never had a need for a preprocessor.

My question is: why do you see such extensive use of preprocessors in C, C++, and Objective-C but rarely (or never) see it in languages like Java, C#, or Scala?

like image 720
cdmckay Avatar asked Aug 12 '09 21:08

cdmckay


2 Answers

I don't know Objective-C, so my answer will be about contrasting the use of the preprocessor in C and C++.

The preprocessor was originally necessary for C for several reasons. If I remember correctly, originally C did not have constants, so #define was needed to avoid magic numbers. Prior to 1999 C did not have inline functions, so again #define was used to create macros or "pseudo-functions" to save the overhead of a function call, while keeping code structured. C also doesn't have run-time or compile-time polymorphism, so #ifdefs were needed for conditional compilation. Compilers were typically not smart enough to optimize away unreachable code, so, again, #ifdefs were used to insert debugging or diagnostic code.

Using the preprocessor in C++ is a throwback to C, and is generally frowned upon. Language features, such as constants, inline functions, and templates can be used in most situations where in C you would have used the preprocessor.

The few cases where the use of a pre-processor in C++ is acceptable or even necessary include the guards for the header files, to prevent the same header from being included multiple times, #ifdef __cplusplus to use the same header for both C and C++, __FILE__ and __LINE__ for logging, and a few others.

The preprocessor is also often used for platform-specific definitions, although C++ Gotchas by Stephen Dewhurst advises having separate include directories for the platform specific definitions, and using them in separate build configurations for each platform.

like image 109
Dima Avatar answered Oct 13 '22 00:10

Dima


The reason why you don't see the preprocessor used in Java, C#, or Scala is that those languages obviously don't have one.

One of the common uses for the C preprocessor is to help provide platform-specific code. Since C (I'm including C++ and Objective-C here) is a low-level language that needs to interface with the operating system directly, in portable code there must necessarily be different sections of the code compiled for different operating systems. You can find extensive examples of this sort of thing in a mature, highly portable code base such as zlib.

As a simple example, to close a network socket one must do something like this (at some level, this can certainly be wrapped in a function but it has to exist somewhere):

#ifdef WIN32
    closesocket(s);
#else
    close(s);
#endif

Newer languages that run on VMs do not need the different platform-specific sections of code, and can be written against the single, portable standard library.

The preprocessor also provides a way to define constants in C, which are provided by other, better, language features in newer languages.

In The Design and Evolution of C++, Bjarne Stroustrup stated that he wanted to remove the dependency on the preprocessor in C++, but was not successful.

like image 37
Greg Hewgill Avatar answered Oct 13 '22 00:10

Greg Hewgill