ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
In the above .c source code you can see a standard include, a forward reference to a subroutine, the actual subroutine, then a call to the subroutine. As you can see, in the above program, I call the subroutine incorrectly, by giving it parameters. That subroutine takes no parameters and returns no parameters. The compiler ignores this error and continues blithely on its way. To the best of my knowledge, this is wrong. The compiler should flag that as an error! Can someone please clue me in on this matter?
Thank you very much.
p.s. I'm using gcc version 10.2.1 20201203 (GCC) on (Void Linux if it makes any difference).
As suggested by posts above, void knurl(); is not the same as void knurl(void);.
The difference may be stated as follows: the first declaration (i.e. not a prototype) does not specify a paramater list while the second declaration which is a prototype specifies an empty parameter list.
Because the first does not specify a parameter list no checks of parameter types are made by the compiler when the function is called. This behavior may be overridden by suitable compiler warning flags as NevemTeve notes.
The reasons for this behavior are discussed here, from which:
Quote:
The reason for supporting the notation is historical. Before the first C standard (C89/C90), you couldn't use prototypes in C; prototypes were one of the biggest and most important features of Standard C. All function declarations, therefore, were written the 'empty parentheses' style (when they were written at all; most functions that returned int were not declared at all). The type void was also added in C89/C90, though some compilers supported it before the standard was finalized.
Because it was crucial to the success of C89/C90 that existing code should mostly continue to work, the empty parentheses style had to be allowed by the standard.
Checking the number and type of arguments to a function which has an old-fashioned definition and no prototype.
Such a feature would work only occasionally—only for calls that appear in the same file as the called function, following the definition. The only way to check all calls reliably is to add a prototype for the function. But adding a prototype eliminates the motivation for this feature. So the feature is not worthwhile.
You can make these visible with -Wstrict-prototypes compile time option.
Seems like I was wrong; now I think in C void knurl();is a prototype -- a prototype that allows arbitrary parameters.
Not true for C++, where it means no parameters (which is void knurl(void); in C).
I bounced between thinking of it as a prototype or a non-prototype declaration, never having thought much about it before now.
I have seen it referred to both ways in references I have read while considering this question. Because the behavior in ANSI C was intended to preserve behavior that predates any support for function prototypes, I have decided to think of it as a non-prototype declaration. That is not authoritative!
UPDATE: When compiling with -Wstrict-prototypes the message produced is:
Code:
gcc prog.c -Wstrict-prototypes
prog.c:3:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
3 | void knurl();
I'll take that as authoritative... enough, and you were right the first time!
Last edited by astrogeek; 01-10-2022 at 02:33 AM.
Reason: added msg
Also, there were two editions of K&R, and C had been around for a long time when the C89 standard came out.
The first C book I read was very old, and it did show the pattern where you declare a function without parameter types, and then define it with the types.
I'm just wondering why behavior described the Kernighan & Ritchie C book is now incorrect?
Fortunately we have a lot of different standards and also a lot of different compilers which may try to follow [largely] those standards (with more or less success).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.