Solved

Why C language multi-line #define command failed when I use '\'

Posted on 2004-08-13
6
1,610 Views
Last Modified: 2011-10-03
Hi,

I  have a struct  S_STYH defined by a multi-line #define command as follows:

#define PUBLIC_STYH                                     \
  char          eyecat[8];                              \
  t_styctx      *styctx;                                \
  t_stydel      *stydel;                                \
  char          *unused_1;                              \
  t_ssdrvex2k   *ssdrvex2k;                             \
  t_ssdrvhtm    *ssdrvhtm;                              \
  t_ssdrvpdf    *ssdrvpdf;                              \
  t_ssdrvps     *ssdrvps;                               \
  Uchar         *nlsBuf;   /* NLS work buffer */        \
  long          nlsBufLen; /* Length of nlsBuf */       \
  t_ssencodeURL *encodeURL;                             \
  t_sscb        styfuns;                                \
  t_stycommons  commons;                                \
  t_ssdrvr      driverInfo;                             \
  t_ssdrvwin    *ssdrvwin;                              \
  t_ssdrvxml    *ssdrvxml;                              \
  t_avlinsert   *avl_insert;                            \
  t_avlcount    *avl_count;                             \
  t_avlcreate   *avl_create;                            \
  t_avlfind     *avl_find;                              \
  t_avlfree     *avl_free;                              \
  union u_drvp  drvp;  /* local statics for a driver */ \
  t_getBackColor *getBackColor;                         \
  R1H           r1h;        /* R1 context */            \
  BOOL_         is_EBCDIC;  /* EBCDIC platform */       \
  t_getDrillArgValue *getDrillArgValue;                 \
  t_cbh         *cbh;                                   \
  Uchar         *utf8Buf;  /* NLS work buffer */        \
  long          utf8BufLen;                             \
  SS_NLSCharTab *nlsCharTab;                            \
  t_intlcmi     *intlcmi;  /* NLS handle */             \
  Uchar         *htmlTrt;   /* TRT for HTML encoding */ \
  t_ssdrvdhtm    *ssdrvdhtm;                            \
  Uchar         *nzapBuf;  /* NLS work buffer */        \
  long          nzapBufLen; /* Length of nlsBuf */      \
  char          *valueBuf;   /* Buffer for field val */ \
  char          *valueBuf2;  /* Buffer for field val */ \
  char          *urlBuf;     /* Buf. for encoded URL */ \
  t_bufCreate   *bufCreate;  /* Generic line buffer  */ \
  t_bufRealloc  *bufRealloc; /* Realloc line buffer  */ \
  t_bufFree     *bufFree;    /* Free line buffer     */
 
/*--- class STYH ---*/
struct  S_STYH {
  PUBLIC_STYH
};

Now I want to add the following new fields into struct  S_STYH:
long          grWidth;                                                          
long          grHeight;                              
long          TwipHeight;                            
long          TwipWidth;                              
char          fileName[256];

To do this, I add these fields directly at the end of the above multi-line #define command as follows:
#define PUBLIC_STYH                                     \
  char          eyecat[8];                              \
  t_styctx      *styctx;                                \
  t_stydel      *stydel;                                \
  char          *unused_1;                              \
  t_ssdrvex2k   *ssdrvex2k;                             \
  t_ssdrvhtm    *ssdrvhtm;                              \
  t_ssdrvpdf    *ssdrvpdf;                              \
  t_ssdrvps     *ssdrvps;                               \
  Uchar         *nlsBuf;   /* NLS work buffer */        \
  long          nlsBufLen; /* Length of nlsBuf */       \
  t_ssencodeURL *encodeURL;                             \
  t_sscb        styfuns;                                \
  t_stycommons  commons;                                \
  t_ssdrvr      driverInfo;                             \
  t_ssdrvwin    *ssdrvwin;                              \
  t_ssdrvxml    *ssdrvxml;                              \
  t_avlinsert   *avl_insert;                            \
  t_avlcount    *avl_count;                             \
  t_avlcreate   *avl_create;                            \
  t_avlfind     *avl_find;                              \
  t_avlfree     *avl_free;                              \
  union u_drvp  drvp;  /* local statics for a driver */ \
  t_getBackColor *getBackColor;                         \
  R1H           r1h;        /* R1 context */            \
  BOOL_         is_EBCDIC;  /* EBCDIC platform */       \
  t_getDrillArgValue *getDrillArgValue;                 \
  t_cbh         *cbh;                                   \
  Uchar         *utf8Buf;  /* NLS work buffer */        \
  long          utf8BufLen;                             \
  SS_NLSCharTab *nlsCharTab;                            \
  t_intlcmi     *intlcmi;  /* NLS handle */             \
  Uchar         *htmlTrt;   /* TRT for HTML encoding */ \
  t_ssdrvdhtm    *ssdrvdhtm;                            \
  Uchar         *nzapBuf;  /* NLS work buffer */        \
  long          nzapBufLen; /* Length of nlsBuf */      \
  char          *valueBuf;   /* Buffer for field val */ \
  char          *valueBuf2;  /* Buffer for field val */ \
  char          *urlBuf;     /* Buf. for encoded URL */ \
  t_bufCreate   *bufCreate;  /* Generic line buffer  */ \
  t_bufRealloc  *bufRealloc; /* Realloc line buffer  */ \
  t_bufFree     *bufFree;    /* Free line buffer     */ \
  long          grWidth;                                \                          
  long          grHeight;                               \
  long          TwipHeight;                           \
  long          TwipWidth;                            \                            
  char          fileName[256];    

But I got a compile error: "C2017: illegal escape sequence".  I also noticed the following: when I only add any one of the five new fields, I got no compile errors. However, whenever I add more than one new field, I immediately got the same compile error. It seems that there could be a limit on the maximum number of lines used in a multi-line #define command, but I find no such restrictions in my C books.

Although I think I may have a work-around to this problem, that is to simply create a new sub-structure under struct  S_STYH, but that is not what I really want to do, also I want to know what causes the problem.

Could you please help me out?

Thank you in advance for your help!

Starkman


0
Comment
Question by:starkman
6 Comments
 
LVL 3

Accepted Solution

by:
pulupul earned 65 total points
ID: 11797920
Firs of all, I would NEVER do such a big define. To track a compiler error caused by that define could lead to headache.
Said that, in the code you pasted there are a lot of spaces after the \ character that follows long grWidth;
Remember that for \ to work in a define, it must be last character in the line, being the only character that follows it the new line character. In your code, you should remove all the spaces after the \ characters.
This is because what \ does is to escape the new line character, so that the preprocessor "sees" all the lines as only one line. If there are spaces (or tab characters, or any other characters) behind the \ character, what is being scaped is the space right after it, and not the new line character, so the effect desired is not achieved.
Hope it helps.
0
 
LVL 22

Expert Comment

by:grg99
ID: 11798172
It's not a good idea to use complex #defines or macros.

#define's are hard to debug because almost ANYTHING can go after #define XXX, there's no syntax checking at all.

You could try looking at the preprocessor output, usually the cpp command lets you see this.   That will often give you a hint as to what the #define is really doing, altho you'll also get a headache looking at all that output.

As otehrs have suggested, it's better to use something with a bit more syntax checking, like a bunch of sub-structs.  

0
 
LVL 86

Expert Comment

by:jkr
ID: 11798256
I agree to all that was said here, but basically your problems stem from the comments (/* ... */) in your big #define statement.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 30 total points
ID: 11798978
It works fine on my compiler(TurboC++ 3.0)

AT the end of the line,
>> long          grWidth;                                \

There was some extra whitespace after the \ which was causing the illegal escape seq. error.

Just realign the last few lines a bit and you'll be fine.

As long as your multi-line comments dont nest,those shouldnt give you an error.
0
 
LVL 7

Assisted Solution

by:JugglerW
JugglerW earned 30 total points
ID: 11801889
Just select follwong lines of your code in your browser and you can easily see that the
\ at the lines grWidth and TwipWidth are followed by many spaces. Just remove them as the other experts above have suggested.

 t_bufFree     *bufFree;    /* Free line buffer     */ \
  long          grWidth;                                \                          
  long          grHeight;                               \
  long          TwipHeight;                           \
  long          TwipWidth;                            \                            
  char          fileName[256];    

0
 

Expert Comment

by:frankbaird
ID: 11810993
C has a mechanism for doing pretty much what you're looking for. It's called typedef.

typedef struct _s_styh
{
   char          eyecat[8];
   t_styctx      *styctx;
   t_stydel      *stydel;
   .
   .
   .
   char          fileName[256];
} s_styh;

To declare a struct of this type you then use
s_styh my_struct;

You can then use my_struct in your program, for example
my_struct.nlsBufLen = 128;

If you need this declaration in several places in your program, put it in a header file and include it.
#include "s_styh.h"
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now