With a structure such as the following
typedef struct
{
size_t StringLength;
char String[1];
} mySTRING;
and use of this structure along these lines
mySTRING * CreateString(char * Input)
{
size_t Len = strlen(Input);
int Needed = sizeof(mySTRING) + Len;
mySTRING * pString = malloc(Needed);
:
strcpy(pString->String, Input);
}
results, on Red Hat Linux cc compiler, in the following warning, which is fair enough.
strings.c:59:3: warning: âstrcpyâ writing 14 bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
strcpy(pString->String, Input);
I know that, in this instance of code, this warning is something I don't need to correct. How can I tell the compiler this without turning off these warnings which might usefully find something, somewhere else, in the future.
What changes can I make to the code to show the compiler this one is OK.
With a structure such as the following
typedef struct
{
size_t StringLength;
char String[1];
} mySTRING;
and use of this structure along these lines
mySTRING * CreateString(char * Input)
{
size_t Len = strlen(Input);
int Needed = sizeof(mySTRING) + Len;
mySTRING * pString = malloc(Needed);
:
strcpy(pString->String, Input);
}
results, on Red Hat Linux cc compiler, in the following warning, which is fair enough.
strings.c:59:3: warning: âstrcpyâ writing 14 bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
strcpy(pString->String, Input);
I know that, in this instance of code, this warning is something I don't need to correct. How can I tell the compiler this without turning off these warnings which might usefully find something, somewhere else, in the future.
What changes can I make to the code to show the compiler this one is OK.
You're using what's commonly referred to as the "struct hack" in order to have an array at the end of the struct have a variable size. That method has always been dubious as far as the C standard is concerned.
The proper way to do that as of the C99 standard is with a flexible array member, which leaves the size of the array unspecified:
typedef struct _mySTRING
{
unsigned short StringLength;
char String[];
} mySTRING;
You'll also need to add 1 to the allocated size, as sizeof(mySTRING)
doesn't include the String
member and you need space for the null terminating byte.
int Needed = sizeof(mySTRING) + Len + 1;
This makes the rest of your code compliant to the C standard.
struct
the same identifier as thetypedef
. This will work because in C, these are separate namespaces. So you can simply remove the_
underscore and can use the identifiermySTRING
for both thestruct
and thetypedef
. This will also work in C++ despite the namespaces not being separate in that language. – Andreas Wenzel Commented Mar 3 at 11:39strcpy
that overflows the destination buffer. Changing from an array of size one to a flexible array member as shown in the answer is changing the meaning of the code - it isn't just cosmetics. – Lundin Commented Mar 4 at 13:00