473,703 Members | 2,375 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C preprocessor function macros with empty aguments

While trying to port some stuff from Unix to Windows, I encountered a
strange behaviour of function macros with empty arguments. Here is a small
snippet which illustrates the problem:

#include <iostream>
#include <string>
using namespace std;

#define B(X, Y) Y

int main()
{
string mystr (B(, "hello world"));
cout << mystr << std::endl;

return 0;
}

This correctly prints 'hello world' when compiled with g++. However, this
program fails to compile on VC++. On going through the preprocessor output
in VC++, I found that the macro call line is:
string mystr ();
This expansion is incorrect.
g++ does the correct expansion (as documented:
http://gcc.gnu.org/onlinedocs/gcc-3....p_3.html#SEC15 )
and the output for the same statement for the g++ preprocessor is:
string mystr ("hello world");

On fiddling around a little more, I realised that the VC++ preprocessor
shifts to the left the non-empty arguments passed, if any. For instance, on
changing the macro definition to:
#define B(X, Y) X X
the statement string mystr (B(, "hello world")); got incorrectly
expanded on VC++ to
string mystr ("hello world" "hello world");
while g++ correctly expanded it to
string mystr ( );

I am using VC++ 6.0

-- Saby


Jul 19 '05 #1
25 9124
Sabyasachi Basu wrote:
This correctly prints 'hello world' when compiled with g++. However, this
program fails to compile on VC++.


So why don't you compile it with g++ then? You can use that in Windows
also to compile windows binaries. You can get mingw from here:

http://www.mingw.org/

Jul 19 '05 #2
Sabyasachi Basu wrote:
int main()
{
string mystr (B( , "hello world"));

^^^

Passing nothing as an argument results in undefined behavior, so neither
preprocessor is "correct." In C99, this behavior is well-defined and
more-or-less works like you'd assume an empty argument should work, but this is
not yet a part of C++.

Regards,
Paul Mensonides
Jul 19 '05 #3
Paul Mensonides wrote:
Sabyasachi Basu wrote:

int main()
{
string mystr (B( , "hello world"));


^^^

Passing nothing as an argument results in undefined behavior, so neither
preprocessor is "correct." In C99, this behavior is well-defined and
more-or-less works like you'd assume an empty argument should work, but this is
not yet a part of C++.

Regards,
Paul Mensonides


I guess the OP could use:

#define EMPTY

// yada yada yada

string mystr(B(EMPTY, "Hello World"));
Jul 19 '05 #4
red floyd wrote:
I guess the OP could use:

#define EMPTY

// yada yada yada

string mystr(B(EMPTY, "Hello World"));


Yes, so long as it only goes through one level of expansion:

#define EMPTY

#define A(x) x

A(EMPTY) // okay

#define X(p) Y(p)
#define Y(p) p

X(EMPTY) // undefined behavior

Regards,
Paul Mensonides
Jul 19 '05 #5
I don't think this behaviour is undefined, going by the GNU documentation,
at least.

Here is what it has to say:
http://gcc.gnu.org/onlinedocs/gcc-3....p_3.html#SEC16
"You can leave macro arguments empty; this is not an error to the
preprocessor (but many macros will then expand to invalid code). You cannot
leave out arguments entirely; if a macro takes two arguments, there must be
exactly one comma at the top level of its argument list. "

Regards,
Saby
"Paul Mensonides" <le******@comca st.net> wrote in message
news:7aW4b.2468 70$cF.79001@rwc rnsc53...
Sabyasachi Basu wrote:
int main()
{
string mystr (B( , "hello world")); ^^^

Passing nothing as an argument results in undefined behavior, so neither
preprocessor is "correct." In C99, this behavior is well-defined and
more-or-less works like you'd assume an empty argument should work, but

this is not yet a part of C++.

Regards,
Paul Mensonides

Jul 19 '05 #6
I am afraid, the path is not open for me. This is a small contrived snippet
of code that I wrote to illustrate the problem. The actual software that I
need to port, runs into hundreds of thousands of lines and it needs to be
compiled with VC++ on Windows.

Regards,
Sabya

"Aggro" <sp**********@y ahoo.com> wrote in message
news:T7******** ****@read3.inet .fi...
Sabyasachi Basu wrote:
This correctly prints 'hello world' when compiled with g++. However, this program fails to compile on VC++.


So why don't you compile it with g++ then? You can use that in Windows
also to compile windows binaries. You can get mingw from here:

http://www.mingw.org/

Jul 19 '05 #7
On Tue, 2 Sep 2003 14:05:03 +0530, "Sabyasachi Basu" <sabya_01 AT hot
mail DOTcom> wrote in comp.lang.c:
I don't think this behaviour is undefined, going by the GNU documentation,
at least.

Here is what it has to say:
http://gcc.gnu.org/onlinedocs/gcc-3....p_3.html#SEC16
"You can leave macro arguments empty; this is not an error to the
preprocessor (but many macros will then expand to invalid code). You cannot
leave out arguments entirely; if a macro takes two arguments, there must be
exactly one comma at the top level of its argument list. "

Regards,
Saby


The GNU compiler does not define the language, the ISO standard does.
Omitting arguments from macros is not now, and never has been, legal
in the C++ language. It is possible to write macros with variable
arguments under the latest C standard, but not in this form.

Visual C++, at least through version 6, does not support this in
either C or C++.

If you want portability, write portable code and do not use
non-standard compiler extensions.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
Jul 19 '05 #8
> I don't think this behaviour is undefined, going by the GNU
documentation,
at least.

Here is what it has to say:
http://gcc.gnu.org/onlinedocs/gcc-3....p_3.html#SEC16
"You can leave macro arguments empty; this is not an error to the
preprocessor (but many macros will then expand to invalid code). You cannot leave out arguments entirely; if a macro takes two arguments, there must be exactly one comma at the top level of its argument list. "


It may be defined behaviour for the G++ compiler, however that doesn't
mean it is defined behaviour according to the C++ standard. The G++
compiler supports several features that are not defined in the C++
standard.

--
Peter van Merkerk
peter.van.merke rk(at)dse.nl
Jul 19 '05 #9
Yes, that would work if there were only level of macro expansion. However,
the following program is closer to what actually exists in my code. The
preprocessor correctly expands EMPTY to blank when expanding the first
level; however, it ends up in the same situation as before when it passes
that blank to the next macro.

#include <iostream>
#include <string>
using namespace std;

#define EMPTY
#define B(X, Y) Y
#define XY(X, Y) \
B(X, Y)

int main()
{
string mystr (XY(EMPTY, "hello world"));
cout << mystr << std::endl;
return 0;
}

Compiling...
testmacro.cpp
C:\Work\testmac ro\testmacro.cp p(14) : warning C4003: not enough actual
parameters for macro 'B'
Linking...
testmacro.obj : error LNK2001: unresolved external symbol "class
std::basic_stri ng<char,struct std::char_trait s<char>,class
std::allocator< char> > __cdecl mystr(void)"
(?mystr@@YA?AV? $basic_string@D U?$char_traits@ D@std@@V?$alloc ator@D@2@@std@@ X
Z)
Debug/testmacro.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

testmacro.exe - 2 error(s), 1 warning(s)
"red floyd" <no*****@here.d ude> wrote in message
news:9K******** **********@news svr25.news.prod igy.com...
#define EMPTY

// yada yada yada

string mystr(B(EMPTY, "Hello World"));

Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

205
10641
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
27
1476
by: Sabyasachi Basu | last post by:
While trying to port some stuff from Unix to Windows, I encountered a strange behaviour of function macros with empty arguments. Here is a small snippet which illustrates the problem: #include <iostream> #include <string> using namespace std; #define B(X, Y) Y
7
23550
by: Newbie_sw2003 | last post by:
Where should I use them? I am giving you my understandings. Please correct me if I am wrong: MACRO: e.g.:#define ref-name 99 The code is substituted by the MACRO ref-name. So no overhead. Execution is faster. Where will it be stotred?(Is it in bss/stack/?) FUNCTION:
4
1949
by: Jim Ford | last post by:
I have a single C file with the following code: int f2() { /* Blah-blah */ } int f1() { /* Blah-blah */
6
3500
by: max(01)* | last post by:
hi. i want to examine preprocessed source which only has certain macros expanded, for example i would like to have: #include <stdio.h> #include "other.c" int main() { ... }
0
8750
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
8662
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9244
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9004
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8961
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5922
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4421
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4679
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2439
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.