The following use of strcat_s shows "C4047: differs in levels of indirection"

267 views Asked by At

What is wrong with the following lines?

//Thanks to Mark
#include <string.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
char datfile[127];
if(argc < 2) return -1;
strcpy_s(datfile, strlen(argv[1]), argv[1]);
strcat_s(datfile, strlen(argv[1]) + 4, ".dat");
printf("%s\n",datfile);//the warning appears here (why?)
return 0;
}

It shows Warning C4047 'function': 'const char *' differs in levels of indirection from 'char'

I've gone through the documentation provided by MSDN for C4047. It names a term called levels of indirection. I've gone through some discussions related with this topic i.e. levels of indirection in the web and (as a newbie) I found those beyond the scope of my radar.

I'd be very glad if someone points out the problem with the code above and provides a simply understandable explanation of the term level of indirection.

1

There are 1 answers

5
Mark Tolonen On

Verifiable example of original error:

#include <string.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    char datfile[127];
    if(argc < 2)
        return -1;
    strcpy_s(datfile, strlen(argv[1]), argv[1]);
    strcat_s(datfile, strlen(argv[1]) + 4, '.dat');
    printf("%s\n",datfile);
    return 0;
}

Output of VS2015 (cl /nologo /W4 test.c):

test.c
test.c(10): warning C4047: 'function': 'const char *' differs in levels of indirection from 'int'
test.c(10): warning C4024: 'strcat_s': different types for formal and actual parameter 3

"level of indirection" indicates mismatch in pointer level. int, int*, int** have different levels of indirection.

With @Mat suggestion this the following line changed to double quotes:

strcat_s(datfile, strlen(argv[1]) + 4, ".dat");

Compiles with no warnings but crashes due to incorrect parameter use. The 2nd parameter to strcpy_s and strcat_s is the length of the destination buffer, not the source string length. Since strlen(arg[v]) doesn't include the nul terminator, the strcpy_s will fail because it will try to copy one more byte than indicated.

Correct use of the 2nd parameter:

#include <string.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    char datfile[127];
    if(argc < 2)
        return -1;
    strcpy_s(datfile, sizeof datfile, argv[1]);
    strcat_s(datfile, sizeof datfile, ".dat");
    printf("%s\n",datfile);
    return 0;
}

Output:

C:\>cl /nologo /W4 test.c
test.c

C:\>test abc
abc.dat