This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: concatenation of string literals
- From: Matt Kraai <kraai at alumni dot cmu dot edu>
- To: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- Cc: gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Fri, 18 Apr 2003 22:06:06 -0700
- Subject: Re: concatenation of string literals
- References: <20030419040812.GA389@ftbfs.org> <200304190427.AAA25350@caip.rutgers.edu>
On Sat, Apr 19, 2003 at 12:27:57AM -0400, Kaveh R. Ghazi wrote:
> See:
>
> http://gcc.gnu.org/ml/gcc/2003-03/msg01508.html
>
> We should probably update README.Portability to reflect this.
The following patch removes the documentation of K+R-specific
restrictions. OK to commit?
Matt
--
Matt Kraai <kraai at alumni dot cmu dot edu>
Debian GNU/Linux Peon
* README.Portability: Remove K+R restrictions.
Index: gcc/README.Portability
===================================================================
RCS file: /cvs/gcc/gcc/gcc/README.Portability,v
retrieving revision 1.9
diff -c -3 -p -r1.9 README.Portability
*** gcc/README.Portability 2 Jul 2002 00:15:42 -0000 1.9
--- gcc/README.Portability 19 Apr 2003 04:59:08 -0000
***************
*** 1,4 ****
! Copyright (C) 2000 Free Software Foundation, Inc.
This file is intended to contain a few notes about writing C code
within GCC so that it compiles without error on the full range of
--- 1,4 ----
! Copyright (C) 2000, 2003 Free Software Foundation, Inc.
This file is intended to contain a few notes about writing C code
within GCC so that it compiles without error on the full range of
*************** the second with common coding pitfalls.
*** 21,56 ****
Portability Issues
==================
- Unary +
- -------
-
- K+R C compilers and preprocessors have no notion of unary '+'. Thus
- the following code snippet contains 2 portability problems.
-
- int x = +2; /* int x = 2; */
- #if +1 /* #if 1 */
- #endif
-
-
- Pointers to void
- ----------------
-
- K+R C compilers did not have a void pointer, and used char * as the
- pointer to anything. The macro PTR is defined as either void * or
- char * depending on whether you have a standards compliant compiler or
- a K+R one. Thus
-
- free ((void *) h->value.expansion);
-
- should be written
-
- free ((PTR) h->value.expansion);
-
- Further, an initial investigation indicates that pointers to functions
- returning void are okay. Thus the example given by "Calling functions
- through pointers to functions" below appears not to cause a problem.
-
-
String literals
---------------
--- 21,26 ----
*************** const char string[] = ("A string");
*** 61,74 ****
This is unfortunate since this is what the GNU gettext macro N_
produces. You need to find a different way to code it.
! K+R C did not allow concatenation of string literals like
!
! "This is a " "single string literal".
!
! Moreover, some compilers like MSVC++ have fairly low limits on the
! maximum length of a string literal; 509 is the lowest we've come
! across. You may need to break up a long printf statement into many
! smaller ones.
Empty macro arguments
--- 31,39 ----
This is unfortunate since this is what the GNU gettext macro N_
produces. You need to find a different way to code it.
! Some compilers like MSVC++ have fairly low limits on the maximum
! length of a string literal; 509 is the lowest we've come across. You
! may need to break up a long printf statement into many smaller ones.
Empty macro arguments
*************** foo (bar, )
*** 88,227 ****
needs to be coded in some other way.
- signed keyword
- --------------
-
- The signed keyword did not exist in K+R compilers; it was introduced
- in ISO C89, so you cannot use it. In both K+R and standard C,
- unqualified char and bitfields may be signed or unsigned. There is no
- way to portably declare signed chars or signed bitfields.
-
- All other arithmetic types are signed unless you use the 'unsigned'
- qualifier. For instance, it is safe to write
-
- short paramc;
-
- instead of
-
- signed short paramc;
-
- If you have an algorithm that depends on signed char or signed
- bitfields, you must find another way to write it before it can be
- integrated into GCC.
-
-
- Function prototypes
- -------------------
-
- You need to provide a function prototype for every function before you
- use it, and functions must be defined K+R style. The function
- prototype should use the PARAMS macro, which takes a single argument.
- Therefore the parameter list must be enclosed in parentheses. For
- example,
-
- int myfunc PARAMS ((double, int *));
-
- int
- myfunc (var1, var2)
- double var1;
- int *var2;
- {
- ...
- }
-
- This implies that if the function takes no arguments, it should be
- declared and defined as follows:
-
- int myfunc PARAMS ((void));
-
- int
- myfunc ()
- {
- ...
- }
-
- You also need to use PARAMS when referring to function protypes in
- other circumstances, for example see "Calling functions through
- pointers to functions" below.
-
- Variable-argument functions are best described by example:-
-
- void cpp_ice PARAMS ((cpp_reader *, const char *msgid, ...));
-
- void
- cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
- {
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, cpp_reader *, pfile);
- VA_FIXEDARG (ap, const char *, msgid);
-
- ...
- VA_CLOSE (ap);
- }
-
- See ansidecl.h for the definitions of the above macros and more.
-
- One aspect of using K+R style function declarations, is you cannot
- have arguments whose types are char, short, or float, since without
- prototypes (ie, K+R rules), these types are promoted to int, int, and
- double respectively.
-
- Calling functions through pointers to functions
- -----------------------------------------------
-
- K+R C compilers require parentheses around the dereferenced function
- pointer expression in the call, whereas ISO C relaxes the syntax. For
- example
-
- typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *));
- *p->handler (pfile, p->arg);
-
- needs to become
-
- (*p->handler) (pfile, p->arg);
-
-
- Macros
- ------
-
- The rules under K+R C and ISO C for achieving stringification and
- token pasting are quite different. Therefore some macros have been
- defined which will get it right depending upon the compiler.
-
- CONCAT2(a,b) CONCAT3(a,b,c) and CONCAT4(a,b,c,d)
-
- will paste the tokens passed as arguments. You must not leave any
- space around the commas. Also,
-
- STRINGX(x)
-
- will stringify an argument; to get the same result on K+R and ISO
- compilers x should not have spaces around it.
-
-
- Passing structures by value
- ---------------------------
-
- Avoid passing structures by value, either to or from functions. It
- seems some K+R compilers handle this differently or not at all.
-
-
- Enums
- -----
-
- In K+R C, you have to cast enum types to use them as integers, and
- some compilers in particular give lots of warnings for using an enum
- as an array index.
-
-
- Bitfields
- ---------
-
- See also "signed keyword" above. In K+R C only unsigned int bitfields
- were defined (i.e. unsigned char, unsigned short, unsigned long.
- Using plain int/short/long was not allowed).
-
-
free and realloc
----------------
--- 53,58 ----
*************** pointer. Thus if mem might be null, you
*** 232,268 ****
free (mem);
- Reserved Keywords
- -----------------
-
- K+R C has "entry" as a reserved keyword, so you should not use it for
- your variable names.
-
-
- Type promotions
- ---------------
-
- K+R used unsigned-preserving rules for arithmetic expresssions, while
- ISO uses value-preserving. This means an unsigned char compared to an
- int is done as an unsigned comparison in K+R (since unsigned char
- promotes to unsigned) while it is signed in ISO (since all of the
- values in unsigned char fit in an int, it promotes to int).
-
- Trigraphs
- ---------
-
- You weren't going to use them anyway, but trigraphs were not defined
- in K+R C, and some otherwise ISO C compliant compilers do not accept
- them.
-
-
Suffixes on Integer Constants
-----------------------------
- K+R C did not accept a 'u' suffix on integer constants. If you want
- to declare a constant to be be unsigned, you must use an explicit
- cast.
-
You should never use a 'l' suffix on integer constants ('L' is fine),
since it can easily be confused with the number '1'.
--- 63,71 ----
*************** long and int are not the same size.
*** 300,321 ****
Second, if you write a function definition with no return type at
all:
! operate (a, b)
! int a, b;
{
...
}
that function is expected to return int, *not* void. GCC will warn
! about this. K+R C has no problem with 'void' as a return type, so you
! need not worry about that.
Implicit function declarations always have return type int. So if you
correct the above definition to
void
! operate (a, b)
! int a, b;
...
but operate() is called above its definition, you will get an error
--- 103,121 ----
Second, if you write a function definition with no return type at
all:
! operate (int a, int b)
{
...
}
that function is expected to return int, *not* void. GCC will warn
! about this.
Implicit function declarations always have return type int. So if you
correct the above definition to
void
! operate (int a, int b)
...
but operate() is called above its definition, you will get an error