Article View: gnu.gcc.help
Article #52667Re: prototypes with short args generate fatal error
From: Paul Eggert
Date: Mon, 08 Jun 1992 21:15
Date: Mon, 08 Jun 1992 21:15
206 lines
7875 bytes
7875 bytes
aab@cichlid.com (Andy Burgess) writes:
> int foo(short x);
> int bar(short x);
> int foo(short x) {} /* this works */
> int bar(x) short x; {} /* this does not */
The C Standard requires a diagnostic for the fourth line,
so GCC is not in error here.
Look under ``promotion of formal parameters'' in the GCC manual.
However, it is an inconvenience for GCC to not allow it as an extension,
particularly since it is a common extension in other C compilers.
Here's a patch for GCC 2.1 to support this usage.
I submitted this patch to the GNU Project,
and I think something like it will appear in a future version of GCC.
Wed Mar 25 19:22:26 1992 Paul Eggert (eggert@twinsun.com)
* c-decl.c (store_parm_decls): Function prototypes now override
old-style definitions if argument types disagree only because of
promotions.
* extend.texi, gcc.texi: Describe this extension to ANSI C.
===================================================================
RCS file: c-decl.c,v
retrieving revision 2.1
diff -u2 -r2.1 c-decl.c
--- c-decl.c 1992/03/23 02:07:53 2.1
+++ c-decl.c 1992/03/26 01:32:34
@@ -5290,26 +5290,30 @@
/* Type for passing arg must be consistent
with that declared for the arg. */
- if (! comptypes (DECL_ARG_TYPE (parm), TREE_VALUE (type))
- /* If -traditional, allow `unsigned int' instead of `int'
- in the prototype. */
- && (! (flag_traditional
- && DECL_ARG_TYPE (parm) == integer_type_node
- && TREE_VALUE (type) == unsigned_type_node)))
- {
+ if (! comptypes (DECL_ARG_TYPE (parm), TREE_VALUE (type)))
+ if (TREE_TYPE (parm) == TREE_VALUE (type))
+ {
+ /* Adjust argument to match prototype. E.g. a previous
+ `int foo(float);' prototype causes
+ `int foo(x) float x; {...}' to be treated like
+ `int foo(float x) {...}'. This is particularly
+ useful for argument types like uid_t. */
+ DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
+#ifdef PROMOTE_PROTOTYPES
+ if (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE
+ && TYPE_PRECISION (TREE_TYPE (parm))
+ < TYPE_PRECISION (integer_type_node))
+ DECL_ARG_TYPE (parm) = integer_type_node;
+#endif
+ if (pedantic)
+ warning ("after promotion, argument `%s' doesn't match function prototype",
+ IDENTIFIER_POINTER (DECL_NAME (parm)));
+ }
+ /* If -traditional, allow `int' argument to match
+ `unsigned' prototype. */
+ else if (! (flag_traditional
+ && TREE_TYPE (parm) == integer_type_node
+ && TREE_VALUE (type) == unsigned_type_node))
error ("argument `%s' doesn't match function prototype",
IDENTIFIER_POINTER (DECL_NAME (parm)));
- if (DECL_ARG_TYPE (parm) == integer_type_node
- && TREE_VALUE (type) == TREE_TYPE (parm))
- {
- error ("a formal parameter type that promotes to `int'");
- error ("can match only `int' in the prototype");
- }
- if (DECL_ARG_TYPE (parm) == double_type_node
- && TREE_VALUE (type) == TREE_TYPE (parm))
- {
- error ("a formal parameter type that promotes to `double'");
- error ("can match only `double' in the prototype");
- }
- }
}
TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = 0;
===================================================================
RCS file: extend.texi,v
retrieving revision 2.1
diff -u2 -r2.1 extend.texi
--- extend.texi 1992/02/27 12:45:33 2.1
+++ extend.texi 1992/03/26 01:47:40
@@ -37,4 +37,5 @@
* Function Attributes:: Declaring that functions have no side effects,
or that they can never return.
+* Function Prototypes:: Prototype declarations and old-style definitions.
* Dollar Signs:: Dollar sign is allowed in identifiers.
* Character Escapes:: @samp{\e} stands for the character @key{ESC}.
@@ -1073,4 +1074,57 @@
for @code{#pragma}. It is basically a mistake to use @code{#pragma} for
@emph{anything}.
+
+@node Function Prototypes
+@section Function Prototype Declarations and Old-Style Function Definitions
+@cindex function prototype declarations
+@cindex old-style function definitions
+@cindex promotion of formal parameters
+
+GNU C extends ANSI C to allow a function prototype to override a later
+old-style non-prototype definition. Consider the following example:
+
+@example
+/* Use prototypes unless the compiler is old-fashioned. */
+#if __STDC__
+# define P((x)) (x)
+#else
+# define P((x)) ()
+#endif
+
+/* prototype function declaration */
+int isroot P((uid_t));
+
+/* old-style function definition */
+int isroot (x)
+ uid_t x;
+@{
+ return x == 0;
+@}
+@end example
+
+Suppose the type @code{uid_t} happens to be @code{short}. ANSI C does
+not allow this example, because subword arguments in old-style
+non-prototype definitions are promoted. Therefore in this example the
+function definition's argument is really an @code{int}, which does not
+match the prototype argument type of @code{short}.
+
+This restriction of ANSI C makes it hard to write code that is portable
+to traditional C compilers, because the programmer does not know
+whether the Posix @code{uid_t} type is @code{short}, @code{int}, or
+@code{long}. Therefore, in cases like these GNU C allows a prototype
+to override a later old-style definition. More precisely, in GNU C, a
+function prototype argument type overrides the argument type specified
+by a later old-style definition if the former type is the same as the
+latter type before promotion. Thus in GNU C the above example is
+equivalent to the following:
+
+@example
+int isroot (uid_t);
+
+int isroot (uid_t x)
+@{
+ return x == 0;
+@}
+@end example
@node Dollar Signs
===================================================================
RCS file: gcc.texi,v
retrieving revision 2.1
diff -u2 -r2.1 gcc.texi
--- gcc.texi 1992/03/22 21:19:05 2.1
+++ gcc.texi 1992/03/26 02:04:37
@@ -1813,26 +1813,4 @@
@end ifclear
-@cindex promotion of formal parameters
-@item
-Users often think it is a bug when GNU CC reports an error for code
-like this:
-
-@example
-int foo (short);
-
-int foo (x)
- short x;
-@{@dots{}@}
-@end example
-
-The error message is correct: this code really is erroneous, because the
-old-style non-prototype definition passes subword integers in their
-promoted types. In other words, the argument is really an @code{int},
-not a @code{short}. The correct prototype is this:
-
-@example
-int foo (int);
-@end example
-
@cindex conflicting types
@cindex scope of declaration
@@ -2390,21 +2368,4 @@
If the compiler produces an error message for valid input, that is a
compiler bug.
-
-Note that the following is not valid input, and the error message for
-it is not a bug:
-
-@example
-int foo (char);
-
-int
-foo (x)
- char x;
-@{ @dots{} @}
-@end example
-
-@noindent
-The prototype says to pass a @code{char}, while the definition says to
-pass an @code{int} and treat the value as a @code{char}. This is what
-the ANSI standard says, and it makes sense.
@cindex invalid input
Technical Details
Message-ID:
<bi'fG5w-@twinsun.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!elroy.jpl.nasa.gov!ucla-cs!twinsun!eggertReferences:
<1992Jun8.174919.25532@cichlid.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 11318c,b21c3ee4f807878a X-Google-Attributes: gid11318c,public X-Google-Thread: 1014db,b21c3ee4f807878a X-Google-Attributes: gid1014db,public X-Google-ArrivalTime: 1992-06-08 09:27:52 PST Newsgroups: gnu.gcc.help,comp.lang.c Path: arc1-ca.pugleaf.net!sparky!uunet!elroy.jpl.nasa.gov!ucla-cs!twinsun!eggert From: eggert@twinsun.com (Paul Eggert) Subject: Re: prototypes with short args generate fatal error Message-ID: <bi'fG5w-@twinsun.com> Sender: usenet@twinsun.com Nntp-Posting-Host: farside Organization: Twin Sun, Inc References: <1992Jun8.174919.25532@cichlid.com> Date: Mon, 8 Jun 1992 21:15:46 GMT Lines: 207