Getting warning when compiling Lisp interperater in C - c

I keep getting a uses gets() warning when trying to compile my interperater and nothing is outputing in the terminal. I changed gets() to fgets() as well but still its not outputing anything and gives me an error:
$ ./littleLisp
warning: this program uses gets(), which is unsafe.
5.000000
littleLisp.c:16:18: error: too few arguments to function call, expected 3, have 1
while (fgets(str) && strcmp(str, "")) {
~~~~~ ^
/usr/include/stdio.h:238:1: note: 'fgets' declared here
char *fgets(char * __restrict, int, FILE *);
^
1 error generated.
make: *** [littleLisp] Error 1
$ make littleLisp
cc littleLisp.c -o littleLisp
littleLisp.c:16:18: error: too few arguments to function call, expected 3, have 1
while (fgets(str) && strcmp(str, "")) {
~~~~~ ^
/usr/include/stdio.h:238:1: note: 'fgets' declared here
char *fgets(char * __restrict, int, FILE *);
^
1 error generated.
make: *** [littleLisp] Error 1
Any idea whats going on?
Here is the gist:
https://gist.github.com/rahul1346/8596118b834ecf41b1d9

As per the man page of fgets(), the syntax is
char *fgets(char *s, int size, FILE *stream);
so, a call to fgets() needs to have three arguments.
In your code, while (fgets(str)....., it has only one.

Related

C compiler error: expected parameter declarator

https://github.com/noyesno/awka
For the above repo, I got the following error when I try to compile it on macOS (gcc is just clang). I have no idea how to fix the problem according to the error message. It compiles fine on Linux.
I also tried the real gcc from Homebrew to compile the package. It also show the same error. How can I fix this problem on macOS?
$ ./configure
$ make
...
gcc -O -Dawka_LIBDIR=\"/usr/local/lib\" -Dawka_INCDIR=\"/usr/local/include\" -c -o print.o print.c
print.c:52:11: error: expected parameter declarator
int PROTO(sprintf, (char *, const char *,...)) ;
^
print.c:52:11: error: expected ')'
print.c:52:11: note: to match this '('
print.c:52:11: error: conflicting types for '__builtin___sprintf_chk'
int PROTO(sprintf, (char *, const char *,...)) ;
^
print.c:52:11: note: '__builtin___sprintf_chk' is a builtin with type 'int (char *, int, unsigned long, const char *, ...)'
3 errors generated.
make[1]: *** [<builtin>: print.o] Error 1
make[1]: Leaving directory '/private/tmp/awka/awka'
make: *** [Makefile:48: awka_exe] Error 2
I'm not going to spend ages on this, but it looks as though configure is gripping stdio.h looking for sprintf. It is unable to find it in the header, and so it adds the #define:
NO_SPRINTF_IN_STDIO
which it sets to 1, and uses it to add its own prototype for sprintf. Unfortunately, this appears to be a macro in this case, which replaces sprintf with '__builtin___sprintf_chk' instead (which has additional string length checks by the looks of it).
Possible solutions:
Comment out the line in print.c, and make sure stdio.h is included somewhere.
After running configure, search for where it defines NO_SPRINTF_IN_STDIO and set that var to 1?
Fix the configure to so a more rigorous test?

c compiler has a function stuck in its namespace (maybe?). mac

A week ago I made a function called getline in a code that didn't work. Since then, whenever I name a function getline and try to compile it, it doesn't work. If I change the name of the function to something else, it works again. I have restarted my computer (though it really shouldn't require that). How can I get this namespace back?
example error message:
Numens-MBP:c examples mycotic$ cc testing.c
testing.c:9:5: error: conflicting types for 'getline'
int getline(void);
^
/usr/include/stdio.h:448:9: note: previous declaration is here
ssize_t getline(char ** __restrict __linep, size_t * __restrict __lineca...
^
testing.c:13:1: warning: type specifier missing, defaults to 'int'
[-Wimplicit-int]
main()
^
testing.c:20:24: error: too few arguments to function call, expected 3, have 0
while ((len = getline()) > 0)
~~~~~~~ ^
/usr/include/stdio.h:448:1: note: 'getline' declared here
ssize_t getline(char ** __restrict __linep, size_t * __restrict __lineca...
^
testing.c:36:5: error: conflicting types for 'getline'
int getline(void)
^
/usr/include/stdio.h:448:9: note: previous declaration is here
ssize_t getline(char ** __restrict __linep, size_t * __restrict __lineca...
^
1 warning and 3 errors generated.
getline() is a standard C library function. Your function is conflicting with the definition in the standard library.
Pick another name for your function. This one is taken.
The getline() function is a part of POSIX 2008; it was not a part of POSIX 2001 or POSIX 1997. On a Mac, even when you specify -std=c11, the POSIX definitions are enabled by default.
You can work around it by specifying a POSIX version that did not support getline(). Consider this code — but ignore the fact that this 'getline()' outputs a line:
#include <stdio.h>
extern int getline(int);
int getline(int num)
{
printf("%s: %d\n", __func__, num);
return num + 1;
}
int main(void)
{
for (int i = 0; i < 5; i++)
printf("RV = %d\n", getline(i));
return 0;
}
When compiled with GCC 7.1.0, or with either the gcc or clang from XCode 8.3.2, generates all sorts of problems because of the conflicting type of getline() from POSIX and getline() as defined in this code unless you add arguments to prevent the problem. The source was in file gl23.c.
$ /usr/bin/clang -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition gl23.c -o gl23
gl23.c:3:12: error: conflicting types for 'getline'
extern int getline(int);
^
/usr/include/stdio.h:448:9: note: previous declaration is here
ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream) __OSX_AVAILABLE_STARTIN...
^
gl23.c:5:5: error: conflicting types for 'getline'
int getline(int num)
^
/usr/include/stdio.h:448:9: note: previous declaration is here
ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream) __OSX_AVAILABLE_STARTIN...
^
gl23.c:14:38: error: too few arguments to function call, expected 3, have 1
printf("RV = %d\n", getline(i));
~~~~~~~ ^
/usr/include/stdio.h:448:1: note: 'getline' declared here
ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream) __OSX_AVAILABLE_STARTIN...
^
3 errors generated.
$
However, if you specify conformance with the old versions of POSIX by adding -D_POSIX_C_SOURCE=200112L or -D_POSIX_C_SOURCE=199506L, then it compiles cleanly, and runs properly, producing:
getline: 0
RV = 1
getline: 1
RV = 2
getline: 2
RV = 3
getline: 3
RV = 4
getline: 4
RV = 5
Be aware that this is only a band-aid solution and it has ramifications — all the other nice new features of POSIX 2008 are no longer accessible.
The only long-term solution is to accept that getline() is now a part of the 'standard' C namespace — the standard is POSIX, of course, not ISO/IEC 9899:2011 — and rename the function. (Yes, it's a nuisance, and K&R 2nd Edition illustrates three versions of getline() that are no longer OK because of this. I had to rename my library function because of this. And the name was not in the reserved namespaces in prior versions of POSIX; there was no way to guess that it would be necessary.)

dlsym - "Too many arguments to function" error

I am doing a C exercise that involves loading a shared library dynamically. When I compile my test program using gcc -o test2 test2.c -ldl command, I get an error:
test2.c: In function ‘main’:
test2.c:27:5: error: too many arguments to function ‘test’
(*test)(array, size);
This is the bit where I get the error:
void (*test)(void);
test = dlsym(handle, "lib_fill_random");
(*test)(array, size);
lib_fill_random is declared with two arguments in both in .h and .c files as void lib_fill_random(double *array, int size);, and it works perfectly fine by itself.
What could be causing this issue?
The function pointer declaration has to match the declaration of the actual function. So it should be:
void (*test)(double *, int);
Your declaration states that the function takes no arguments, so you get an error when you call it with arguments.

errors occurred while compiling on gcc

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main(void)
{
int a,b,sub,i,count=0;char buffer[20],w[20];
scanf("%d",&a);
scanf("%d",&b);
sub=a-b;
if(sub>0)
{
scanf("%s",w); /*wrong answer*/
itoa(sub,buffer,10);
int l=strlen(buffer);
for(i=0;i<l;i++)
{
if(w[i]==buffer[i])
count++;
}
((count==l || count==l-1) && w[0]!='0') ? printf("accepted") : printf("Not accepted");
}
else printf("Sub operation returned negative value");
}
The output of the compiler is
prog.c:4:6: warning: return type of 'main' is not 'int' [-Wmain]
void main(void)
^
prog.c: In function 'main':
prog.c:13:1: warning: implicit declaration of function 'itoa' [-Wimplicit-function-declaration]
itoa(sub,buffer,10);
^
/home/HCDVgj/ccHBnrc7.o: In function `main':
prog.c:(.text.startup+0x61): undefined reference to `itoa'
collect2: error: ld returned 1 exit status
I did not use any long int variables but i still get ld return 1 exists. how to debug these errors
int main() This is teh first thing you should do.
scanf("%19s",w); This is better.
itoa is non standard (so you will not find it in any standard implementaion) better use snprintf()
printf('%s",((count==l || count==l-1) && w[0]!='0') ? "accepted" : "Not accepted"); More compact I would say.
Use of snprintf
snprintf(target, size_of_target1, "%d", source2);
sprintf takes no parameter specifying the number of bytes to write which may lead to buffer overflow which is not a good thing.
1 : In bytes
2 : source is in integer here
Few things worth mentioning to clear your idea or to be more precise
The output you specified is not output of the c program ... in the process of compilation your compiler run into error and then it generates those output. -CiaPan
main() shouldn't be of void return type it is expected to return 0 in case of normal termination. Abnormal termination is usually signaled by a non-zero.-David C. Rankin
I don't know why you're talking about "long int variables".
The first warning can be fixed by changing void main(void) to int main(void) and adding a return 0; at the end.
The second warning tells you that the compiler doesn't know what itoa is.
The following linker error tells you that the linker (ld) also doesn't know what itoa is, and that's why compilation fails.
The reason itoa is unknown is that it's not a standard function and not available on your platform.

How to implement custom versions of the getline function in stdio.h (CLANG, OS X) (ANSWER: Change POSIX standard used to compile) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Good evening,
I am working through the exercises in Kernighan's and Ritchie's classic "The C Programming Language".
In several places the exercises have you creating your own version of a function that duplicates the name of of a function in the standard library. Instead of creating an alternate name for my version, I would really like to tell the compiler that I would rather use my version of the function then the standard library function.
To get specific, if I try to compile a solution to exercise 1-18 which removes trailing blanks and tabs from each line of input I use a function 'getline' to read in the line from stdin. Unfortunately, this generates a compiler error because getline is defined in stdio.h.
I have tried using #undef, but couldn't seem to get that to work.
I have searched for other prior similar questions and found [this one][1]; however, it seems to require hacking the standard library header which I would rather not do.
Thank you for your help in advance.
Here is the code (stripped of my comments for shortness):
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1000
static size_t getline(char s[], size_t lim) {
char c;
size_t i = 0;
while (--lim > 0 && (c = (char)getchar()) != (char)EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
int main(void) {
char line[MAXLINE] = "";
size_t len = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > MAXLINE)
printf("%s", line);
exit(EXIT_SUCCESS);
}
And, the error I get is:
cc -std=c99 -Wall -g -I. -c -o obj/cleantrailsnblanks.o cleantrailsnblanks.c
cleantrailsnblanks.c:14:15: error: static declaration of 'getline' follows non-static declaration
static size_t getline(char s[], size_t lim) {
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
^
cleantrailsnblanks.c:35:40: error: too few arguments to function call, expected 3, have 2
while ((len = getline(line, MAXLINE)) > 0)
~~~~~~~ ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:1: note: 'getline' declared here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
^
2 errors generated.
make: *** [obj/cleantrailsnblanks.o] Error 1
UPDATE 1
After I dropped 'static' from my definition, the error changes to:
cc -std=c99 -Wall -g -I. -c -o obj/cleantrailsnblanks.o cleantrailsnblanks.c
cleantrailsnblanks.c:14:8: error: conflicting types for 'getline'
size_t getline(char s[], size_t lim) {
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
^
cleantrailsnblanks.c:35:40: error: too few arguments to function call, expected 3, have 2
while ((len = getline(line, MAXLINE)) > 0)
~~~~~~~ ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:1: note: 'getline' declared here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
^
2 errors generated.
make: *** [obj/cleantrailsnblanks.o] Error 1
ANSWER
Refer to this discussion: Why do I get a "conflicting types for getline" error when compiling the longest line example in chapter 1 of K&R2?
The solution is to add these two lines prior to including stdio.h:
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
This sets the compiles the code using the POSIX.1-2001 standard as opposed to the POSIX.1-2008 standard in which the GNU getline() extension was added to the standard.
Refer to these two discussions (the second is the most relevant):
Why do I get a "conflicting types for getline" error when compiling the longest line example in chapter 1 of K&R2?
Can an ANSI C-compliant implementation include additional functions in its standard library?
The solution is to add these two lines prior to including stdio.h:
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
This sets the compiles the code using the POSIX.1-2001 standard as opposed to the POSIX.1-2008 standard in which the GNU getline() extension was added to the standard.
I think your exercice want to make you learn the dynamic injection and shared library.
Compile your file (without the static) like gcc -shared -o libname.so filename.c
On OS X you will need to set 3 environment variable :
setenv DYLD_LIBRARY_PATH .
setenv DYLD_INSERT_LIBRARIES libname.so
setenv DYLD_FORCE_FLAT_NAMESPACE 1
Some others information : http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
EDIT
Let me show you an exemple by changing the result of id
$> id
uid=501(yourname) gid(staff) groups ...
Create a file getuid.c
int getuid() {
return (0);
}
int geteuid() {
return (0);
}
Compile with gcc -shared -o myuid.so getuid.c
You can write nm myuid.so and see the function inside.
then set your environment variable
setenv DYLD_LIBRARY_PATH .
setenv DYLD_INSERT_LIBRARIES libname.so
setenv DYLD_FORCE_FLAT_NAMESPACE 1
it's could be with export, depends of your shell.
then id result look like :
$> id
uid=0(yourname) gid(staff) groups ...
K&R is a (very) old book now, you need to take that in account. Declare/define getline exactly as the manual says (actually). As you are on OSX, the manual says:
SYNOPSIS
#include <stdio.h>
ssize_t
getline(char ** restrict linep, size_t * restrict linecapp, FILE * restrict stream);
Use that prototype.
You may also change the exercise a little bit and rename the function as mygetline if you really wish to use the original prototype.
It depends on how you're going to use it.
If it's just in one .c file, I'd change your method name to something else, then either change all the calls to your new name or add a #define realName overrideName at the top of your file.
If this is more generic, or for mocking in unit testing, I would take your overridden getline method into its own .c file. Compiler it to a .so then tell your system about your override .so file before any other libraries when starting your app.

Resources