Solved

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

Posted on 2004-08-13
6
1,624 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

690 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