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

Popular posts from this blog

javascript - Thinglink image not visible until browser resize -

firebird - Error "invalid transaction handle (expecting explicit transaction start)" executing script from Delphi -

mongodb - How to keep track of users making Stripe Payments -