C program won't compile without warnings when GCC is called by makefile - Works otherwise -
so have program here, works when called
$ gcc test.c -o test -std=c99
but when called in makefile:
all: test test: test.c gcc test.c -o test -std=c99
it produces warnings instead , gives segmentation fault.
terminal output:
gcc -g test.c -o tester -std=c99 test.c: in function ‘test_split’: test.c:43:2: warning: implicit declaration of function‘strdup[-wimplicit-function-declaration] char *str_cpy = strdup(str); // allow mutation of original string test.c:43:18: warning: initialization makes pointer integer without cast [enabled default] char *str_cpy = strdup(str); // allow mutation of original string
above error not appear otherwise , not produse segmentation fault.
the code segment fails here. string.h included in header. file large file test other functions.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #define cnrm "\x1b[0m" #define cred "\x1b[31m" #define cgrn "\x1b[32m" int stringsum(char *s); void stringsum2(char *s, int *res); int distance_between(char *s, char c); char *string_between(char *s, char c); char **split(char *s); static int test_num = 1; static void logger(int passed, char *s) { char *res; char *color; if (passed) { res = "pass"; color = cgrn; } else { res = "fail"; color = cred; } printf("[test %d][%s%s%s] %s\n", test_num++, color, res, cnrm, s); } static void test_split(char *str, char **correct) { int i, pass = 1; char buf[512] = { 0 }; char *str_cpy = strdup(str); // allow mutation of original string char **res = split(str_cpy); if (!res || !res[0]) { pass = 0; sprintf(buf, "split() returned null or empty array"); goto end; } (i = 0; correct[i]; i++) { if (!res[i]) { pass = 0; sprintf(buf, "split() returned fewer words expected"); goto end; } } if (res[i]) { pass = 0; sprintf(buf, "split() returned more words expected"); goto end; } sprintf(buf, "\n%-16s%-16s\n", "returned", "expected"); (i = 0; res[i]; i++) { char tmp[256] = { 0 }; sprintf(tmp, "%-16s%-16s\n", res[i], correct[i]); strcat(buf, tmp); if (strcmp(res[i], correct[i])) { pass = 0; goto end; } } end: logger(pass, buf); free(str_cpy); } static void test_stringsum(char *input, int expected) { int test; char buf[256] = { 0 }; test = stringsum(input); sprintf(buf, "returned: %d, expected: %d", test, expected); logger(test == expected, buf); } static void test_distance_between(char *str, char c, int expected) { int test; char buf[256] = { 0 }; test = distance_between(str, c); sprintf(buf, "returned: %d, expected: %d", test, expected); logger(test == expected, buf); } static void test_string_between(char *str, char c, const char *expected) { char *res_char; char buf[256] = { 0 }; res_char = string_between(str, c); snprintf(buf, sizeof(buf), "returned: %s, expected: %s", res_char, expected); if (!res_char && expected) { logger(0, buf); } else { if (!expected) logger(!res_char, buf); else logger(!strcmp(res_char, expected), buf); free(res_char); } } static void test_stringsum2(char *input, int expected) { int res_int; char buf[256] = { 0 }; stringsum2(input, &res_int); sprintf(buf, "returned: %d, expected: %d", res_int, expected); logger(res_int == expected, buf); } int main(void) { printf("testing stringsum()\n"); test_stringsum("abcd", 10); test_stringsum("a!", -1); test_stringsum("aazz", 54); test_stringsum("ababcdcabcddabcdabcabcabcddabcddabcabcddabcabcdd", 120); test_stringsum("", 0); test_num = 1; printf("\ntesting distance_between()\n"); test_distance_between("a1234a", 'a', 5); test_distance_between("a1234", 'a', -1); test_distance_between("123456a12334a123a", 'a', 6); test_distance_between("", 'a', -1); test_num = 1; printf("\ntesting string_between()\n"); test_string_between("a1234a", 'a', "1234"); test_string_between("a1234", 'a', null); test_string_between("a123adette er svaretaasd2qd3asd12", 'a', "dette er sv"); test_string_between("", 'a', null); test_num = 1; printf("\ntesting stringsum2()\n"); test_stringsum2("abcd", 10); test_stringsum2("abcd!", -1); test_stringsum2("bbbdbbbbbdbbdbbbbbddbbbbbdbbdbbbbdbd", 90); test_stringsum2("", 0); test_num = 1; printf("\ntesting split()\n"); test_split("abcd", (char *[]){ "abcd", null }); test_split("hei du", (char *[]){ "hei", "du", null }); test_split("dette er mange ord", (char *[]){ "dette", "er", "mange", "ord", null }); return 0; }
any ideas?
edit: added full code.
strdup()
defined bunch of standards (svr4, 4.3bsd, posix.1-2001), not c standard. if specify -std=c99
, gcc default disables functions defined in these standards. warning "implicit declaration" because c has (annoying) legacy feature of declaring functions implicitly, if call them, rules such return type int
, in case doesn't match assignment char*
. these warnings should always fix.
in case, -std=c99
, can fixed using feature test macros.
the linked manual page tells in cases function declaration included, example build without problems:
gcc test.c -o test -std=c99 -d_posix_c_source=200809l
or gcc can use this, enables pretty features of libc.
gcc test.c -o test -std=c99 -d_gnu_source
you add define in .c file normal #define
before include relevant system headers. may better have @ same place -std=c99
though (ie. command line option), because here kinda goes that.
a more extreme solution switch -std=gnu99
. think doing that, because easy accidentally use language features aren't standard c. , run more porting trouble, writing few functions, if need port software other c compiler doesn't have gnu extensions.
Comments
Post a Comment