LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-06-2010, 02:00 AM   #1
ravishekhar.82
Member
 
Registered: Feb 2010
Posts: 30

Rep: Reputation: 15
Question #define in C++


Hi,

I am new to C++ and having some problem in using #define.

if I use # define like as follows it works fine

Code:
#include<iostream>
    using namespace std;
    #define abc(x) ( ((x) < 0) ? -(x) : (x) ) 
    int i=10;
    
   int main() 
   {
	
	abc(i);
	cout << "Hello World!" << endl;
	return 0;
   }

But if I use as below :

Code:
#include<iostream>
    using namespace std;
    #define abc(x) ( ((x) < 0) ? -(x) : (x) ) 
    int i=10;
    abc(i);
   int main() 
   {
	
	cout << "Hello World!" << endl;
	return 0;
   }

I am getting error
expected `)' before '<' token

My application need that abs(i) to be outside main only.

How to achieve that. Please suggest.

Last edited by ravishekhar.82; 04-06-2010 at 02:28 AM. Reason: changed abs(x) to abc(x) .
 
Old 04-06-2010, 02:16 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
It would appear not the #define that you are struggling with but more the appropriate place
for your call to abs(i).

Firstly I would urge against using a predefined function (ie abs is already defined in C++)

Secondly, what would you expect to happen if in your second example you change:

abs(i);

to

cout <<i<<endl;

Hopefully the answer will show you what has happened?
 
1 members found this post helpful.
Old 04-06-2010, 02:25 AM   #3
ravishekhar.82
Member
 
Registered: Feb 2010
Posts: 30

Original Poster
Rep: Reputation: 15
Quote:
Firstly I would urge against using a predefined function (ie abs is already defined in C++)
I have changed it to say abc(x). Still same problem.

Quote:
Secondly, what would you expect to happen if in your second example you change:

abs(i); to cout <<i<<endl;
I am getting expected constructor, destructor, or type conversion before ‘<<’ token

I am not clear what you expect me to get from this.

My question is Is it possible to call abc(i) outside main(){} ?

If yes, then how ?

Last edited by ravishekhar.82; 04-06-2010 at 02:27 AM.
 
Old 04-06-2010, 02:32 AM   #4
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
No.
 
1 members found this post helpful.
Old 04-06-2010, 02:33 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Hmm ... my question would be why you would want too?

I assume you are learning and so using some kind of book / web page.
You seem to have jumped in a little deep and I think you need to start at the beginning.

Basically you are outside any defined function and therefore deemed to be setting global
variables. If you expand your #define on the line where you abc(i), what would you get?

Once expanded, if we assume it could work, what value would there be in executing that code there?
 
1 members found this post helpful.
Old 04-06-2010, 02:56 AM   #6
rigor
Member
 
Registered: Sep 2003
Location: 19th moon ................. ................Planet Covid ................Another Galaxy;............. ................Not Yours
Posts: 705

Rep: Reputation: Disabled
Even if this:

Code:
#include<iostream>
using namespace std;
#define my_abs(x) ( ( x < 0 ) ? ( -x ) : x )
int i=10;
int abs_i = my_abs(i) ;
int main()
{
    cout << "Hello World!" << endl;
    return 0;
}
represents more like what you were trying to do, in the sense of

1) Not replace a standard "function"
2) Not throw away the chosen value

I'm still not quite clear on why you'd want to do what you're
doing, unless what you're showing us in incomplete, you intend
to change it later, you're just focusing on the error.

As far as the macro, it might be helpful for you to see what
happens when it's expanded. If you compile it this way:

Code:
gcc -E program_name.C -o program_name.Cpp
ignore most of the junk you'll see in the file, go to
the end of the file, in that area of the file, you'll see
actual expansion of your macro.
 
1 members found this post helpful.
Old 04-06-2010, 03:47 AM   #7
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
First look at the following code:
Code:
#include<iostream>
using namespace std;
#define abc(x) ( ((x) < 0) ? -(x) : (x) ) 
int i=-10;
int j = abc(i);
 
int main() 
{
   cout << j << endl;
   cout << i << endl;
   cout << abc(i) << endl;
   cout << i << endl;
   cout << "Hello World!" << endl;
   return 0;
}
A #define can be used in the global space when initialising a global variable. But you can't put statements in the global space. Just try and put i++; before main, you'll get a compile time error.

Your line abc(i) in the global space was the same as putting a statement there, hence the errors that you received.

Finally, it's good to know about #define's but it is generally agreed that they shouldn't be used. C++ has a better alternative, namely inline'd functions which are less prone to bugs.
 
1 members found this post helpful.
Old 04-06-2010, 05:51 AM   #8
ravishekhar.82
Member
 
Registered: Feb 2010
Posts: 30

Original Poster
Rep: Reputation: 15
Hi,

First of all thanks I got it that C++ is not allowing to do what basically I am trying to do.
Just for clarification, the program I put that is just for example not the actual one.
I even believe C have the same constrain too else C++ could have allowed that too ( b'coz we can compile C program with g++ too)

I have some other doubt (I don't know it is right to place to ask it) in kernel(2.6.23) code.

In mm/swapfile.c part of code looks like

Code:
   #include <asm/tlbflush.h>
   #include <linux/swapops.h>
   DEFINE_SPINLOCK(swap_lock);
   
   unsigned int nr_swapfiles;
   long total_swap_pages;
   static int swap_overflow;
In include/linux/spinlock_types.h DEFINE_SPINLOCK() is there as

Code:
   
  #define SPIN_LOCK_UNLOCKED      __SPIN_LOCK_UNLOCKED(old_style_spin_init) 
  #define RW_LOCK_UNLOCKED        __RW_LOCK_UNLOCKED(old_style_rw_init)

 #define DEFINE_SPINLOCK(x)      spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
 
  #define DEFINE_RWLOCK(x)        rwlock_t x = __RW_LOCK_UNLOCKED(x)
How this is getting resolved and getting compiled without any error etc ?

Thanks

Last edited by ravishekhar.82; 04-06-2010 at 06:03 AM.
 
Old 04-06-2010, 06:01 AM   #9
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
This would be some of the trickiness that graemef was referring too, but essentially you need to track back through the
previous #defines as well to get the full picture. So if you use the following you should be able to workout what the final line looks like:

Code:
#ifdef CONFIG_DEBUG_SPINLOCK
# define __SPIN_LOCK_UNLOCKED(lockname)                 \
    (spinlock_t)    {   .raw_lock = __RAW_SPIN_LOCK_UNLOCKED,   \
                .magic = SPINLOCK_MAGIC,        \
                .owner = SPINLOCK_OWNER_INIT,       \
                .owner_cpu = -1,            \
                SPIN_DEP_MAP_INIT(lockname) }
#define __RW_LOCK_UNLOCKED(lockname)                    \
    (rwlock_t)  {   .raw_lock = __RAW_RW_LOCK_UNLOCKED, \
                .magic = RWLOCK_MAGIC,          \
                .owner = SPINLOCK_OWNER_INIT,       \
                .owner_cpu = -1,            \
                RW_DEP_MAP_INIT(lockname) }
#else
# define __SPIN_LOCK_UNLOCKED(lockname) \
    (spinlock_t)    {   .raw_lock = __RAW_SPIN_LOCK_UNLOCKED,   \
                SPIN_DEP_MAP_INIT(lockname) }
#define __RW_LOCK_UNLOCKED(lockname) \
    (rwlock_t)  {   .raw_lock = __RAW_RW_LOCK_UNLOCKED, \
                RW_DEP_MAP_INIT(lockname) }
#endif
Just choose one of the __SPIN_LOCK_UNLOCKED definitions to use and replace it where it appears in the snippet you have copied.
 
Old 04-06-2010, 06:18 AM   #10
ravishekhar.82
Member
 
Registered: Feb 2010
Posts: 30

Original Poster
Rep: Reputation: 15
Hi,

I am putting first code again which is in mm/swapfile.c :

Code:
   #include <asm/tlbflush.h>
   #include <linux/swapops.h>

   DEFINE_SPINLOCK(swap_lock);
   
   unsigned int nr_swapfiles;
   long total_swap_pages;
   static int swap_overflow;
Why there is no error at the line (Bold One ) where DEFINE_SPINLOCK(swap_lock);. It is also a preprocessor as was mine abc(x)( if I am not wrong ).
 
Old 04-06-2010, 06:53 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Yes, but what does it expand too????

You have to do some of the work here otherwise we will end up with how long is a piece of string
(ie the questions will never end as this is the same concept just ongoing)
 
Old 04-06-2010, 07:02 AM   #12
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Quote:
Originally Posted by ravishekhar.82 View Post
Why there is no error at the line (Bold One ) where DEFINE_SPINLOCK(swap_lock);. It is also a preprocessor as was mine abc(x)( if I am not wrong ).
This is because the #define expands to the definition of a variable. x is declared to be of type spinlock_t and it is assigned the value, which is returned by the expanding of the macro __SPIN_LOCK_UNLOCKED(x).

This is one of the reasons macros are frowned upon by many people, they hide what is really going on.
 
1 members found this post helpful.
Old 04-06-2010, 07:03 AM   #13
ravishekhar.82
Member
 
Registered: Feb 2010
Posts: 30

Original Poster
Rep: Reputation: 15
Hi,

Okay I got your point.
If in my example I do like following. it will work.
Code:
     #include<iostream>
    using namespace std;
    #define abc(x) int x=10 
    
    abc(i);

   int main() 
   {
	
	cout << "Hello World!" << endl;
	return 0;
   }
Thanks for the reply. Got the error and also bit of concept cleared.

Marking this as Solved.

Thanks

Last edited by ravishekhar.82; 04-06-2010 at 07:05 AM.
 
  


Reply

Tags
c++, linux



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with a #define Wynd Programming 4 04-22-2007 03:30 PM
m4 define in a define Four Programming 0 03-04-2007 09:41 PM
define jhon Linux - Networking 2 08-30-2004 07:42 PM
define main linuxanswer Programming 8 11-05-2003 02:02 PM
using #define Jo_Nak Programming 4 06-11-2003 01:46 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:09 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration