473,395 Members | 1,870 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Preprocessor Question

emaghero
Greetings one and all,

I have a query about the preprocessor directive.

I am coding in C++ in the MS Visual Studio environment.

I was updating an old code recently where I had defined PI using the #define directive.

Expand|Select|Wrap|Line Numbers
  1. #define PI 3.1415926535897932385
  2.  
I decided to change this to

Expand|Select|Wrap|Line Numbers
  1. #define PI 4.0*atan(1.0)
  2.  
And the code ceased to work correctly. I think what is happening is that when I divide by PI it is dividing by 4.0 and multiplying atan(1.0).

I didn't think this was supposed to happen with #define.

What is the reason for this?

Does the compiler call PI or does it replace PI with 4.0*atan(1.0) when it is seen?

Is this a compiler dependent problem?
Dec 11 '08 #1
4 2055
Banfa
9,065 Expert Mod 8TB
As you correctly titled this thread #define is a preprocessor directive. The preprocessor is NOT the compiler and only deals with preprocessor commands. The compiler can not handle preprocessor commands, they are not a part of the real language syntax.

When a #define is used the preprocessor does a text substitution of the symbol name with the text text it is defined to so for your #define the code
double oneoverpi = 1 / PI;
is converted by the preprocessor to
double oneoverpi = 1.0 / 4.0*atan(1.0);
The compiler then compiles this using the normal operator precedence rules so effectively it does calculate (1.0 / 4.0)*atan(1.0).

This is a known gotcha with #defines, you should always surround your #define with parenthesis which avoids the problem
Expand|Select|Wrap|Line Numbers
  1. # #define PI (4.0*atan(1.0))
  2.  
  3. double oneoverpi = 1 / PI;
  4.  
  5. // after preprocessing
  6.  
  7. double oneoverpi = 1 / (4.0*atan(1.0));  // Calculation is correct
  8.  
No "calling" is done it is entirely text substitution.

One final thought is that in C++ certainly it would be considered best practice not to use a #define for this at all but to use constant which then has the added benefit of proper type checking.
Expand|Select|Wrap|Line Numbers
  1. static const double PI = 4.0*atan(1.0);
Dec 11 '08 #2
donbock
2,426 Expert 2GB
Another issue to consider is that a #define macro that expands to a function call can't be used in file-scope initializers.

Another issue to consider is performance. The atan() function will be called every time execution passes through a statement that refers to PI, including each pass through a loop.
Dec 11 '08 #3
weaknessforcats
9,208 Expert Mod 8TB
Another issue is that macros that expand into a function stall the debugger since the code is not in the implementation but only the macro.

Another issue is that there is no control on how the macro is applied. This means it can be expanded into code that won't compile or that produces indeterminate results.

etc..etc...

There are several C++ features specifically designed to replace macros:
1) templates
2) inline functions
3) namespaces
4) enums

Use these in C++ rather than macos.
Dec 11 '08 #4
Thanks very much for all your help.
Dec 13 '08 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

205
by: Jeremy Siek | last post by:
CALL FOR PAPERS/PARTICIPATION C++, Boost, and the Future of C++ Libraries Workshop at OOPSLA October 24-28, 2004 Vancouver, British Columbia, Canada http://tinyurl.com/4n5pf Submissions
24
by: Nudge | last post by:
I have an array, and an unrolled loop which looks like this: do_something(A); do_something(A); .... do_something(A); I thought: why should I type so much? I should write a macro. So I was...
4
by: Jim Ford | last post by:
I have a single C file with the following code: int f2() { /* Blah-blah */ } int f1() { /* Blah-blah */
13
by: Chris Croughton | last post by:
Is the following code standard-compliant, and if so what should it do? And where in the standard defines the behaviour? #include <stdio.h> #define DEF defined XXX int main(void) { int...
3
by: Avin Patel | last post by:
Hi, I have written C# code. And I have used preprocessor / macro in it. I want to get the C# code after processing preprocessor, I have defined durcng compile time. How can I get this code? ...
32
by: spibou | last post by:
Is the output of the C preprocessor deterministic ? What I mean by that is , given 2 compilers which conform to the same standard, will their preprocessors produce identical output given as input...
6
by: ludovicd | last post by:
Hi to all, There is my question, Let's say I got a fonction which takes a numeric argument long enough so that there has to be spaces in it to represent it correctly. (Ex. 0xf63a002c5ff0338ec...
31
by: Sam of California | last post by:
Is it accurate to say that "the preprocessor is just a pass in the parsing of the source file"? I responded to that comment by saying that the preprocessor is not just a pass. It processes...
10
by: abir | last post by:
Hi, This is not strictly a C++ language question. Is there any way to form a string from an identifier with the preprocessor with some operations ? i.e to say to make a string from an...
9
by: Bob | last post by:
Hi, Is it possible to change the references in a project by using preprocessor directives? Thanks, Bob
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.