DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 9 of 9

Thread: #define vs. const

  1. #1
    Join Date
    May 2004
    Posts
    242

    #define vs. const

    Hello,

    I'm trying to understand the fundamental differences between define and const.

    I tried :-

    #include<iostream>

    using namespace std;

    #define num -2
    const int NUMBER = -2;

    int main()
    {
    int x = -NUMBER;
    cout << "x = [" << x << "]\n";

    int y = -num;
    cout << "y = [" << y << "]\n";
    return 0;

    }

    I'm getting on both occasions 2 as a result.

    Can someone explain why you'd use const and not #define ?

    Thanks,

    Imanuel.

  2. #2
    Join Date
    Oct 2007
    Posts
    369
    In your example, either way is fine.
    If you use a static const in a class definition, you have a name-scoped constant: MyClass::MyConstant.
    If you use a #define, you end up with no name-space scoping: you just have MyConstant.
    This can lead to name collisions in code that includes the class definition.

  3. #3
    Join Date
    Dec 2003
    Posts
    3,366
    Defines are a pre-processor macro, of the simplest sort, which replace every token with the constant value. It is exactly the same as using a constant value in the code... for example

    #define three 3.0
    foo(three);
    foo(3.0);

    both of the calls to foo are exactly the same -- they will create the same assembly language code. The macro is useful if it is used many times and you want to change the value in one place to affect many uses.

    const float three = 3.0; is very different. It is strongly typed for c++ and you know it is a float (without a suffix, the 3.0 might really be a double!). You can take its address, should your function require a pointer to a float instead. It is the "better" way to do a constant, however there can be a bit of bloat attached to it (the macro is pure and cannot create bloat if you have a suffix, leaving the suffix off can create casting bloat) depending on how smart your compiler is and how you used it.

  4. #4
    Join Date
    Dec 2003
    Posts
    3,366
    the following really brings home that the compiler, or at least visual c++, creates a full on float and the associated bloat of memory reads, writes, etc.

    The following prints 2.0 in .net 2005:

    #define three 3.0;
    const float th = 3.0;
    float * fp;

    fp = (float *)& th;
    fp[0] = 2;
    printf("%f\n", th); //2.0

    Note that trying to do similar hacks to the macro are impossible -- you cannot take the address of a macro constant, it is the pure thing and hopefully the constant is wired into the assembly language without the extra memory access etc (you never know, some compiler could make a mess here).

  5. #5
    Join Date
    Oct 2005
    Location
    Maady
    Posts
    1,819
    #define as a macro concept can hold a complete instructions,

    for example you can :

    Code:
    #define Amahdy cout<<"Hello world";
    main()
     Amahdy
    }
    but of course you can't do the same thing with constants, as they only hold a value of a datatype or objeect , and never an instruction like this ...
    and here is another example :

    Code:
    #define DevX "Hello World !"
    #define Forums cout<<
    
    main()
    {
    Forums DevX; //similar to cout<<"...";
    //and use them anywhere else :
    Forums "ByAmahdy !";
    }
    Programmer&Cracker CS
    MyBlog:Blog.Amahdy.com
    MyWebsite:www.Amahdy.com

  6. #6
    Join Date
    Nov 2003
    Posts
    4,118
    There are many differences between #defines and const. const is an object and you can take its address, for example. It's also type safe -- the compiler knows what the constant's type is. All these do not apply to #defines. In addition, you will find that some debuggers can't handle #defines properly so you won;t be able to print the name of the macro and see what it stands for.
    Danny Kalev

  7. #7
    Join Date
    Mar 2007
    Location
    Bangalore, India
    Posts
    247
    Bjarne Stroustrup had commented somewhere about some issues in using #define (marcros). They are not always safe, and could lead to hard to find bugs, especially if the macro is in another file. I will give you a very simple example:

    Code:
    #include <iostream>
    
    #define FIVE 2+3
    const int five = 2+3;
    
    
    using namespace std;
    
    int main()
    {
      int TWENTYFIVE = FIVE * FIVE;
      int twentfive = five * five;
    
      cout<< TWENTFIVE <<endl;
      cout<< twentfive <<endl;
    
      return 0;
    }
    This is just one of the examples. Here if you change the macro to

    #define FIVE (2+3)

    there won't be any problem.

    The fundamental difference is that macros are not compiled. Instead, the pre-processor replaces the occurances of the macro with the content. Ie, for the above example, the input to the compiler is actually:

    Code:
    #include <iostream>
    
    const int five = 2+3;
    
    
    using namespace std;
    
    int main()
    {
      int TWENTYFIVE = 2 + 3 * 2 + 3;
      int twentfive = five * five;
    
      cout<< TWENTFIVE <<endl;
      cout<< twentfive <<endl;
    
      return 0;
    }
    The part in maroon is done by the pre-processor, and it is what the compiler gets.
    Last edited by Razee Marikar; 11-16-2007 at 01:49 AM. Reason: Correction of mistake (compiler expects instead of compiler gets)

  8. #8
    Join Date
    Dec 2003
    Posts
    3,366
    But I showed you that const is not safe either, a simple pointer mistake in your code can re-value the constant forever... you can always find a way to claim something is "unsafe". Const is better, cleaner c++ code (always, always avoid a macro if you can!) -- but its not perfect and in embedded code the macro can be superior for some specialized reasons.

  9. #9
    Join Date
    Mar 2007
    Location
    Bangalore, India
    Posts
    247
    I am not saying that const is safe; nor that it is unmodifiable. But there are many many problems with #define s that it must be avoided when possible (like when you need a constant, use a const. When you need a constant in a class, use a static const, and so on), and that #define gives you result which you may find hard to debug. Agreed that 3.0f and 3.0 makes a big difference, but a C++ programmer ought to be aware of it. The problems associated with #defines are far less obvious, and most probably will be overlooked. If you do not try to take the address of a static const, an optimizing compiler may not allocate memory for it. I give one more example why #defines are unsafe. Check out the following code:
    Code:
    #include <iostream>
    
    #define X 1;
    #define Y 2;
    
    
    using namespace std;
    
    int main(void)
    {
     int a = X + Y;
     cout << a << endl;
     return 0;
    }
    At first look, many will expect this program to output 3. But the problem here is that like a statement in C++, a semi column was used for #define.

Similar Threads

  1. Screen Capture Bug
    By Ranger in forum VB Classic
    Replies: 3
    Last Post: 05-29-2006, 09:43 PM
  2. Screen Capture Bug
    By Ranger in forum VB Classic
    Replies: 0
    Last Post: 12-09-2000, 01:21 PM
  3. How do I detect an FTP timeout?
    By Julian Milano in forum VB Classic
    Replies: 2
    Last Post: 08-11-2000, 12:11 PM
  4. How do I detect an FTP timeout?
    By Julian Milano in forum VB Classic
    Replies: 0
    Last Post: 08-10-2000, 09:16 PM
  5. Trying to print a PDF File from VB
    By Kunal Sharma in forum VB Classic
    Replies: 2
    Last Post: 04-25-2000, 03:45 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center