LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-09-2022, 01:11 PM   #1
jr_bob_dobbs
Member
 
Registered: Mar 2009
Distribution: Bedrock, Devuan, Slackware, Linux From Scratch, Void
Posts: 651
Blog Entries: 135

Rep: Reputation: 188Reputation: 188
Question C: parser failing to see an error


Code:
#include <stdio.h>

void knurl();

void knurl()
{
}


int main()
{
  knurl(27, 82, 14);
}
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).
 
Old 01-09-2022, 01:24 PM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Maybe you forgot to enable warnings, such as `function call without prototype`.
In C (unliky C++) this is not a prototype:
Code:
void knurl();
This is:
Code:
void knurl(void);
 
3 members found this post helpful.
Old 01-09-2022, 02:21 PM   #3
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
(I wasn't sure if the new C standard allowed function overloading.)

Same thought as NevemTeve, what compile flags did you use, excepting just a default compile.

Also what compile did you use, while gcc seems reasonable, I think you can also use c++, maybe even g++
 
Old 01-09-2022, 03:39 PM   #4
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,264
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
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.
UPDATE: I found this related reference in the GNU GCC documentation, Certain Changes We Don't Want to Make:

Quote:
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.

The above is correct through at least gcc-10.3.0 and C17. A change being considered for C2x is to make empty parenthesis equivalent to (void) in function declarations, but I am unsure of the details and status at this time.

Last edited by astrogeek; 01-10-2022 at 01:21 AM.
 
3 members found this post helpful.
Old 01-09-2022, 04:18 PM   #5
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,225

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
Okay, this is terrifying...

I don't get any warnings when compiling with gcc and "-Wall and -Wextra".

I did get a warning from clang-tidy:

Code:
kurl.c:11:21: warning: too many arguments in call to 'knurl' [clang-diagnostic-warning]
 
Old 01-09-2022, 07:15 PM   #6
EdGr
Member
 
Registered: Dec 2010
Location: California, USA
Distribution: I run my own OS
Posts: 998

Rep: Reputation: 470Reputation: 470Reputation: 470Reputation: 470Reputation: 470
Use the C++ compiler even if you are writing C. C++ will flag the error.
Ed
 
Old 01-10-2022, 01:08 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,842

Rep: Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309
You can check -Wstrict-prototypes for example.
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html (look for prototypes and declaration related options)
 
3 members found this post helpful.
Old 01-10-2022, 01:21 AM   #8
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
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).
 
1 members found this post helpful.
Old 01-10-2022, 01:34 AM   #9
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,264
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
Quote:
Originally Posted by NevemTeve View Post
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
 
2 members found this post helpful.
Old 01-12-2022, 02:28 PM   #10
jr_bob_dobbs
Member
 
Registered: Mar 2009
Distribution: Bedrock, Devuan, Slackware, Linux From Scratch, Void
Posts: 651

Original Poster
Blog Entries: 135

Rep: Reputation: 188Reputation: 188
Holy cow, thanks for the all of the replies.

I find myself a bit bewildered. I'm just wondering why behavior described the Kernighan & Ritchie C book is now incorrect?

I guess the impression I'm getting is ... things got changed that break backwards compatibility with (what used to be) correct C.

Anyway, the immediate fix of
Code:
/* cc -o test_delete test_delete.c */
#include <stdio.h>

void knurl(void);

void knurl(void)
{
}


int main()
{
  knurl(27, 82, 14);
}
now correctly sees the call to knurl as an error, So thank you all for that.
 
Old 01-12-2022, 02:37 PM   #11
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Regarding KR-C: let's not forget it has been written some 40 years ago.
https://en.m.wikipedia.org/wiki/The_...mming_Language

Last edited by NevemTeve; 01-12-2022 at 02:41 PM.
 
Old 01-12-2022, 05:33 PM   #12
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,225

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
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.

Last edited by dugan; 01-12-2022 at 05:35 PM.
 
Old 01-13-2022, 01:18 AM   #13
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,842

Rep: Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309Reputation: 7309
Quote:
Originally Posted by jr_bob_dobbs View Post
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).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
checking for XML::Parser... configure: error: XML::Parser perl module is required for kornerr Linux - General 11 11-16-2008 07:24 AM
Inkscape compilation error: *** [extension/internal/pdfinput/pdf-parser.o] Error 1 w1k0 Slackware 12 10-25-2008 09:53 AM
eth1 failing on boot, IEEE firewire card driver failing, help jackuss_169 Linux - Laptop and Netbook 5 03-05-2005 07:34 AM
LILO install failing, Boot failing, but Installation fine. sramelyk Slackware 9 08-23-2003 02:37 PM
X failing to load; AddScreen/InitScreen failing for driver 0 weblion Linux - Software 1 08-01-2002 06:14 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:14 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration