Related
Now before people start marking this a dup, I've read all the following, none of which provide the answer I'm looking for:
C FAQ: What's wrong with casting malloc's return value?
SO: Should I explicitly cast malloc()’s return value?
SO: Needless pointer-casts in C
SO: Do I cast the result of malloc?
Both the C FAQ and many answers to the above questions cite a mysterious error that casting malloc's return value can hide; however, none of them give a specific example of such an error in practice. Now pay attention that I said error, not warning.
Now given the following code:
#include <string.h>
#include <stdio.h>
// #include <stdlib.h>
int main(int argc, char** argv) {
char * p = /*(char*)*/malloc(10);
strcpy(p, "hello");
printf("%s\n", p);
return 0;
}
Compiling the above code with gcc 4.2, with and without the cast gives the same warnings, and the program executes properly and provides the same results in both cases.
anon#anon:~/$ gcc -Wextra nostdlib_malloc.c -o nostdlib_malloc
nostdlib_malloc.c: In function ‘main’:
nostdlib_malloc.c:7: warning: incompatible implicit declaration of built-in function ‘malloc’
anon#anon:~/$ ./nostdlib_malloc
hello
So can anyone give a specific code example of a compile or runtime error that could occur because of casting malloc's return value, or is this just an urban legend?
Edit I've come across two well written arguments regarding this issue:
In Favor of Casting: CERT Advisory: Immediately cast the result of a memory allocation function call into a pointer to the allocated type
Against Casting (404 error as of 2012-02-14: use the Internet Archive Wayback Machine copy from 2010-01-27.{2016-03-18:"Page cannot be crawled or displayed due to robots.txt."})
You won't get a compiler error, but a compiler warning. As the sources you cite say (especially the first one), you can get an unpredictable runtime error when using the cast without including stdlib.h.
So the error on your side is not the cast, but forgetting to include stdlib.h. Compilers may assume that malloc is a function returning int, therefore converting the void* pointer actually returned by malloc to int and then to your pointer type due to the explicit cast. On some platforms, int and pointers may take up different numbers of bytes, so the type conversions may lead to data corruption.
Fortunately, modern compilers give warnings that point to your actual error. See the gcc output you supplied: It warns you that the implicit declaration (int malloc(int)) is incompatible to the built-in malloc. So gcc seems to know malloc even without stdlib.h.
Leaving out the cast to prevent this error is mostly the same reasoning as writing
if (0 == my_var)
instead of
if (my_var == 0)
since the latter could lead to a serious bug if one would confuse = and ==, whereas the first one would lead to a compile error. I personally prefer the latter style since it better reflects my intention and I don't tend to do this mistake.
The same is true for casting the value returned by malloc: I prefer being explicit in programming and I generally double-check to include the header files for all functions I use.
One of the good higher-level arguments against casting the result of malloc is often left unmentioned, even though, in my opinion, it is more important than the well-known lower-level issues (like truncating the pointer when the declaration is missing).
A good programming practice is to write code, which is as type-independent as possible. This means, in particular, that type names should be mentioned in the code as little as possible or best not mentioned at all. This applies to casts (avoid unnecessary casts), types as arguments of sizeof (avoid using type names in sizeof) and, generally, all other references to type names.
Type names belong in declarations. As much as possible, type names should be restricted to declarations and only to declarations.
From this point of view, this bit of code is bad
int *p;
...
p = (int*) malloc(n * sizeof(int));
and this is much better
int *p;
...
p = malloc(n * sizeof *p);
not simply because it "doesn't cast the result of malloc", but rather because it is type-independent (or type-agnositic, if you prefer), because it automatically adjusts itself to whatever type p is declared with, without requiring any intervention from the user.
Non-prototyped functions are assumed to return int.
So you're casting an int to a pointer. If pointers are wider than ints on your platform, this is highly risky behavior.
Plus, of course, that some people consider warnings to be errors, i.e. code should compile without them.
Personally, I think the fact that you don't need to cast void * to another pointer type is a feature in C, and consider code that does to be broken.
If you do this when compiling in 64-bit mode, your returned pointer will be truncated to 32-bits.
EDIT:
Sorry for being too brief. Here's an example code fragment for discussion purposes.
main()
{
char * c = (char *)malloc(2) ;
printf("%p", c) ;
}
Suppose that the returned heap pointer is something bigger than what is representable in an int, say 0xAB00000000.
If malloc is not prototyped to return a pointer, the int value returned will initially be in some register with all the significant bits set. Now the compiler say, "okay, how do I convert and int to a pointer". That's going to be either a sign extension or zero extension of the low order 32-bits that it has been told malloc "returns" by omitting the prototype. Since int is signed I think the conversion will be sign extension, which will in this case convert the value to zero. With a return value of 0xABF0000000 you'll get a non-zero pointer that will also cause some fun when you try to dereference it.
A Reusable Software Rule:
In the case of writing an inline function in which used malloc(), in order to make it reusable for C++ code too, please do an explicit type casting (e.g. (char*)); otherwise compiler will complain.
A void pointer in C can be assigned to any pointer without an explicit cast. The compiler will give warning but it can be reusable in C++ by type casting malloc() to corresponding type. With out type casting also it can be use in C, because C is no strict type checking. But C++ is strictly type checking so it is needed to type cast malloc() in C++.
The malloc() function could often require a conversion cast before.
For the returned type from malloc it is a pointer to void and not a particular type, like may be a char* array, or a string.
And sometimes the compiler could not know, how to convert this type.
int size = 10;
char* pWord = (char*)malloc(size);
The allocation functions are available for all C packages.
So, these are general functions, that must work for more C types.
And the C++ libraries are extensions of the older C libraries.
Therefore the malloc function returns a generic void* pointer.
Cannot allocate an object of a type with another of different type.
Unless the objects are not classes derived from a common root class.
And not always this is possible, there are different exceptions.
Therefore a conversion cast might be necessary in this case.
Maybe the modern compilers know how to convert different types.
So this could not be a great issue, when is doing this conversion.
But a correct cast can be used, if a type conversion is possible.
As an example: it cannot be cast "apples" to "strawberries". But these both, so called "classes", can be converted to "fruits".
There are custom structure types, which cannot be cast directly.
In this case, any member variable has to be assigned separately.
Or a custom object would have to set its members independently.
Either if it is about a custom object class, or whatever else...
Also a cast to a void pointer must be used when using a free call.
This is because the argument of the free function is a void pointer.
free((void*)pWord);
Casts are not bad, they just don't work for all the variable types.
A conversion cast is also an operator function, that must be defined.
If this operator is not defined for a certain type, it may not work.
But not all the errors are because of this conversion cast operator.
With kind regards, Adrian Brinas
Hi after going through answer here
1: Do I cast the result of malloc? I understood that one of the reason why we do not cast malloc is that
casting malloc is redundant
But what I am still trying to figure out is the warning that will be suppressed when we do cast the malloc function
I also read this answer but I have the follwing doubts
#include<stdio.h>
main()
{
int *a=malloc(20);
}
I understood the point in the answer that compiler will think that malloc returns an int while we are trying to give that value to an int * which will gives us error cannot convert from int * to int or something like that but the basic question is
Won't the compiler in absence of stdlib.h treat malloc as a user defined function and wont it look for the declaration of it and it will give some error related to missing delcaration/defination
In the original C language - C89/90 - calling an undeclared function is not an error. For this reason, a pre-C99 compiler will not produce any "error" due to a missing function declaration. The compiler will simply assume that function returns an int.
It will also automatically and quietly "guess" (infer, derive) the function parameter types from the argument types you supplied in your call. In your example, you supplied 20, which will make the compiler to guess that the "unknown" malloc function takes a single parameter of type int. Note that this is also incorrect, because the real malloc takes a size_t parameter.
In C99 and later the function declaration is required. Which means that forgetting to declare malloc (e.g. forgetting to include <stdlib.h>) is indeed an error, which will result in a diagnostic message. (The parameter-guessing behavior is still there in the language though.)
Note also that in C99 and later declaring function main without an explicit return type int is illegal. The "implicit int" rule is specific to the original version of C language specification only. It no longer exists in C99 and later. You have to declare it as int main(... explicitly.
In the absence of stdlib.h the compiler thinks that the malloc() function will return int(For C89/90 and not from c99) and you are trying to assign that value to int * and hence there is a type mismatch and the compiler will report it
As you can see from the code snippet below, I have declared one char variable and one int variable. When the code gets compiled, it must identify the data types of variables str and i.
Why do I need to tell again during scanning my variable that it's a string or integer variable by specifying %s or %d to scanf? Isn't the compiler mature enough to identify that when I declared my variables?
#include <stdio.h>
int main ()
{
char str [80];
int i;
printf ("Enter your family name: ");
scanf ("%s",str);
printf ("Enter your age: ");
scanf ("%d",&i);
return 0;
}
Because there's no portable way for a variable argument functions like scanf and printf to know the types of the variable arguments, not even how many arguments are passed.
See C FAQ: How can I discover how many arguments a function was actually called with?
This is the reason there must be at least one fixed argument to determine the number, and maybe the types, of the variable arguments. And this argument (the standard calls it parmN, see C11(ISO/IEC 9899:201x) §7.16 Variable arguments ) plays this special role, and will be passed to the macro va_start. In another word, you can't have a function with a prototype like this in standard C:
void foo(...);
The reason why the compiler can not provide the necessary information is simply, because the compiler is not involved here. The prototype of the functions doesn't specify the types, because these functions have variable types. So the actual data types are not determined at compile time, but at runtime.
The function then takes one argument from the stack, after the other. These values don't have any type information associated with it, so the only way, the function knows how to interpret the data is, by using the caller provided information, which is the format string.
The functions themselves don't know which data types are passed in, nor do they know the number of arguments passed, so there is no way that printf can decide this on it's own.
In C++ you can use operator overloading, but this is an entire different mechanism. Because here the compiler chooses the appropriate function based on the datatypes and available overloaded function.
To illustrate this, printf, when compiled looks like this:
push value1
...
push valueN
push format_string
call _printf
And the prototype of printf is this:
int printf ( const char * format, ... );
So there is no type information carried over, except what is provided in the format string.
printf is not an intrinsic function. It's not part of the C language per se. All the compiler does is generate code to call printf, passing whatever parameters. Now, because C does not provide reflection as a mechanism to figure out type information at run time, the programmer has to explicitly provide the needed info.
Compiler may be smart, but functions printf or scanf are stupid - they do not know what is the type of the parameter do you pass for every call. This is why you need to pass %s or %d every time.
The first parameter is a format string. If you're printing a decimal number, it may look like:
"%d" (decimal number)
"%5d" (decimal number padded to width 5 with spaces)
"%05d" (decimal number padded to width 5 with zeros)
"%+d" (decimal number, always with a sign)
"Value: %d\n" (some content before/after the number)
etc, see for example Format placeholders on Wikipedia to have an idea what format strings can contain.
Also there can be more than one parameter here:
"%s - %d" (a string, then some content, then a number)
Isn't the compiler matured enough to identify that when I declared my
variable?
No.
You're using a language specified decades ago. Don't expect modern design aesthetics from C, because it's not a modern language. Modern languages will tend to trade a small amount of efficiency in compilation, interpretation or execution for an improvement in usability or clarity. C hails from a time when computer processing time was expensive and in highly limited supply, and its design reflects this.
It's also why C and C++ remain the languages of choice when you really, really care about being fast, efficient or close to the metal.
scanf as prototype int scanf ( const char * format, ... ); says stores given data according to the parameter format into the locations pointed by the additional arguments.
It is not related with compiler, it is all about syntax defined for scanf.Parameter format is required to let scanf know about the size to reserve for data to be entered.
GCC (and possibly other C compilers) keep track of argument types, at least in some situations. But the language is not designed that way.
The printf function is an ordinary function which accepts variable arguments. Variable arguments require some kind of run-time-type identification scheme, but in the C language, values do not carry any run time type information. (Of course, C programmers can create run-time-typing schemes using structures or bit manipulation tricks, but these are not integrated into the language.)
When we develop a function like this:
void foo(int a, int b, ...);
we can pass "any" number of additional arguments after the second one, and it is up to us to determine how many there are and what are their types using some sort of protocol which is outside of the function passing mechanism.
For instance if we call this function like this:
foo(1, 2, 3.0);
foo(1, 2, "abc");
there is no way that the callee can distinguish the cases. There are just some bits in a parameter passing area, and we have no idea whether they represent a pointer to character data or a floating point number.
The possibilities for communicating this type of information are numerous. For example in POSIX, the exec family of functions use variable arguments which have all the same type, char *, and a null pointer is used to indicate the end of the list:
#include <stdarg.h>
void my_exec(char *progname, ...)
{
va_list variable_args;
va_start (variable_args, progname);
for (;;) {
char *arg = va_arg(variable_args, char *);
if (arg == 0)
break;
/* process arg */
}
va_end(variable_args);
/*...*/
}
If the caller forgets to pass a null pointer terminator, the behavior will be undefined because the function will keep invoking va_arg after it has consumed all of the arguments. Our my_exec function has to be called like this:
my_exec("foo", "bar", "xyzzy", (char *) 0);
The cast on the 0 is required because there is no context for it to be interpreted as a null pointer constant: the compiler has no idea that the intended type for that argument is a pointer type. Furthermore (void *) 0 isn't correct because it will simply be passed as the void * type and not char *, though the two are almost certainly compatible at the binary level so it will work in practice. A common mistake with that type of exec function is this:
my_exec("foo", "bar", "xyzzy", NULL);
where the compiler's NULL happens to be defined as 0 without any (void *) cast.
Another possible scheme is to require the caller to pass down a number which indicates how many arguments there are. Of course, that number could be incorrect.
In the case of printf, the format string describes the argument list. The function parses it and extracts the arguments accordingly.
As mentioned at the outset, some compilers, notably the GNU C Compiler, can parse format strings at compile time and perform static type checking against the number and types of arguments.
However, note that a format string can be other than a literal, and may be computed at run
time, which is impervious to such type checking schemes. Fictitious example:
char *fmt_string = message_lookup(current_language, message_code);
/* no type checking from gcc in this case: fmt_string could have
four conversion specifiers, or ones not matching the types of
arg1, arg2, arg3, without generating any diagnostic. */
snprintf(buffer, sizeof buffer, fmt_string, arg1, arg2, arg3);
It is because this is the only way to tell the functions (like printf scanf) that which type of value you are passing. for example-
int main()
{
int i=22;
printf("%c",i);
return 0;
}
this code will print character not integer 22. because you have told the printf function to treat the variable as char.
printf and scanf are I/O functions that are designed and defined in a way to receive a control string and a list of arguments.
The functions does not know the type of parameter passed to it , and Compiler also cant pass this information to it.
Because in the printf you're not specifying data type, you're specifying data format. This is an important distinction in any language, and it's doubly important in C.
When you scan in a string with with %s, you're not saying "parse a string input for my string variable." You can't say that in C because C doesn't have a string type. The closest thing C has to a string variable is a fixed-size character array that happens to contain a characters representing a string, with the end of string indicated by a null character. So what you're really saying is "here's an array to hold the string, I promise it's big enough for the string input I want you to parse."
Primitive? Of course. C was invented over 40 years ago, when a typical machine had at most 64K of RAM. In such an environment, conserving RAM had a higher priority than sophisticated string manipulation.
Still, the %s scanner persists in more advanced programming environments, where there are string data types. Because it's about scanning, not typing.
Is declaring an header file essential? This code:
main()
{
int i=100;
printf("%d\n",i);
}
seems to work, the output that I get is 100. Even without using stdio.h header file. How is this possible?
You don't have to include the header file. Its purpose is to let the compiler know all the information about stdio, but it's by no means necessary if your compiler is smart (or lazy).
You should include it because it's a good habit to get into - if you don't, then the compiler has no real way to know if you're breaking the rules, such as with:
int main (void) {
puts (7); // should be a string.
return 0;
}
which compiles without issue but rightly dumps core when running. Changing it to:
#include <stdio.h>
int main (void) {
puts (7);
return 0;
}
will result in the compiler warning you with something like:
qq.c:3: warning: passing argument 1 of ‘puts’ makes pointer
from integer without a cast
A decent compiler may warn you about this, such as gcc knowing about what printf is supposed to look like, even without the header:
qq.c:7: warning: incompatible implicit declaration of
built-in function ‘printf’
How is this possible? In short: three pieces of luck.
This is possible because some compilers will make assumptions about undeclared functions. Specifically, parameters are assumed to be int, and the return type also int. Since an int is often the same size as a char* (depending on the architecture), you can get away with passing ints and strings, as the correct size parameter will get pushed onto the stack.
In your example, since printf was not declared, it was assumed to take two int parameters, and you passed a char* and an int which is "compatible" in terms of the invocation. So the compiler shrugged and generated some code that should have been about right. (It really should have warned you about an undeclared function.)
So the first piece of luck was that the compiler's assumption was compatible with the real function.
Then at the linker stage, because printf is part of the C Standard Library, the compiler/linker will automatically include this in the link stage. Since the printf symbol was indeed in the C stdlib, the linker resolved the symbol and all was well. The linking was the second piece of luck, as a function anywhere other than the standard library will need its library linked in also.
Finally, at runtime we see your third piece of luck. The compiler made a blind assumption, the symbol happened to be linked in by default. But - at runtime you could have easily passed data in such a way as to crash your app. Fortunately the parameters matched up, and the right thing ended up occurring. This will certainly not always be the case, and I daresay the above would have probably failed on a 64-bit system.
So - to answer the original question, it really is essential to include header files, because if it works, it is only through blind luck!
As paxidiablo said its not necessary but this is only true for functions and variables but if your header file provides some types or macros (#define) that you use then you must include the header file to use them because they are needed before linking happens i.e during pre-processing or compiling
This is possible because when C compiler sees an undeclared function call (printf() in your case) it assumes that it has
int printf(...)
signature and tries to call it casting all the arguments to int type. Since "int" and "void *" types often have same size it works most of the time. But it is not wise to rely on such behavior.
C supprots three types of function argument forms:
Known fixed arguments: this is when you declare function with arguments: foo(int x, double y).
Unknown fixed arguments: this is when you declare it with empty parentheses: foo() (not be confused with foo(void): it is the first form without arguments), or not declare it at all.
Variable arguments: this is when you declare it with ellipsis: foo(int x, ...).
When you see standard function working then function definition (which is in form 1 or 3) is compatible with form 2 (using same calling convention). Many old std. library functions are so (as desugned to be), because they are there form early versions of C, where was no function declarations and they all was in form 2. Other function may be unintentionally be compatible with form 2, if they have arguments as declared in argument promotion rules for this form. But some may not be so.
But form 2 need programmer to pass arguments of same types everywhere, because compiler not able to check arguments with prototype and have to determine calling convention osing actual passed arguments.
For example, on MC68000 machine first two integer arguments for fixed arg functions (for both forms 1 and 2) will be passed in registers D0 and D1, first two pointers in A0 and A1, all others passed through stack. So, for example function fwrite(const void * ptr, size_t size, size_t count, FILE * stream); will get arguments as: ptr in A0, size in D0, count in D1 and stream in A1 (and return a result in D0). When you included stdio.h it will be so whatever you pass to it.
When you do not include stdio.h another thing happens. As you call fwrite with fwrite(data, sizeof(*data), 5, myfile) compiler looks on argruments and see that function is called as fwrite(*, int, int, *). So what it do? It pass first pointer in A0, first int in D0, second int in D1 and second pointer in A1, so it what we need.
But when you try to call it as fwrite(data, sizeof(*data), 5.0, myfile), with count is of double type, compiler will try to pass count through stack, as it is not integer. But function require is in D1. Shit happens: D1 contain some garbage and not count, so further behaviour is unpredictable. But than you use prototype defined in stdio.h all will be ok: compiler automatically convert this argument to int and pass it as needed. It is not abstract example as double in arument may be just result of computation involving floating point numbers and you may just miss this assuming result is int.
Another example is variable argument function (form 3) like printf(char *fmt, ...). For it calling convention require last named argument (fmt here) to be passed through stack regardess of its type. So, then you call printf("%d", 10) it will put pointer to "%d" and number 10 on stack and call function as need.
But when you do not include stdio.h comiler will not know that printf is vararg function and will suppose that printf("%d", 10) is calling to function with fixed arguments of type pointer and int. So MC68000 will place pointer to A0 and int to D0 instead of stack and result is again unpredictable.
There may be luck that arguments was previously on stack and occasionally read there and you get correct result... this time... but another time is will fail. Another luck is that compiler takes care if not declared function may be vararg (and somehow makes call compatible with both forms). Or all arguments in all forms are just passed through stack on your machine, so fixed, unknown and vararg forms are just called identically.
So: do not do this even you feel lucky and it works. Unknown fixed argument form is there just for compatibility with old code and is strictly discouraged to use.
Also note: C++ will not allow this at all, as it require function to be declared with known arguments.
int main()
{
int j=97;
char arr[4]="Abc";
printf(arr,j);
getch();
return 0;
}
this code gives me a stack overflow error why?
But if instead of printf(arr,j) we use printf(arr) then it prints Abc.
please tell me how printf works , means 1st argument is const char* type so how arr is
treated by compiler.
sorry! above code is right it doesn't give any error,I write this by mistake. but below code give stack overflow error.
#include <stdio.h>
int main()
{
int i, a[i];
getch();
return 0;
}
since variable i take any garbage value so that will be the size of the array
so why this code give this error when i use DEV C++ and if I use TURBO C++ 3.0 then
error:constant expression required displayed. if size of array can't be variable then when
we take size of array through user input.no error is displayed. but why in this case.
please tell me how printf works
First of all, pass only non-user supplied or validated strings to the first argument of printf()!
printf() accepts a variable number of arguments after the required const char* argument (because printf() is what's called a variadic function). The first const char* argument is where you pass a format string so that printf() knows how to display the rest of your arguments.
If the arr character array contains user-inputted values, then it may cause a segfault if the string happens to contain those formatting placeholders, so the format string should always be a hard-coded constant (or validated) string. Your code sample is simple enough to see that it's really a constant, but it's still good practice to get used to printf("%s", arr) to display strings instead of passing them directly to the first argument (unless you absolutely have to of course).
That being said, you use the formatting placeholders (those that start with %) to format the output. If you want to display:
Abc 97
Then your call to printf() should be:
printf("%s %d", arr, j);
The %s tells printf() that the second argument should be interpreted as a pointer to a null-terminated string. The %d tells printf() that the third argument should be interpreted as a signed decimal.
this code gives me a stack overflow error why?
See AndreyT's answer.
I see that now the OP changed the description of the behavior to something totally different, so my explanation no longer applies to his code. Nevertheless, the points I made about variadic functions still stand.
This code results in stack invalidation (or something similar) because you failed to declare function printf. printf is a so called variadic function, it takes variable number of arguments. In C language it has [almost] always been mandatory to declare variadic functions before calling them. The practical reason for this requirement is that variadic functions might (and often will) require some special approach for argument passing. It is often called a calling convention. If you forget to declare a variadic function before calling it, a pre-C99 compiler will assume that it is an ordinary non-variadic function and call it as an ordinary function. I.e. it will use a wrong calling convention, which in turn will lead to stack invalidation. This all depends on the implementation: some might even appear to "work" fine, some will crash. But in any case you absolutely have to declare variadic functions before calling them.
In this case you should include <stdio.h> before calling printf. Header file <stdio.h> is a standard header that contains the declaration of printf. You forgot to do it; hence the error (most likely). There's no way to be 100% sure, since it depends on the implementation.
Otherwise, your code is valid. The code is weird, since you are passing j to printf without supplying a format specifier for it, but it is not an error - printf simply ignores extra variadic arguments. Your code should print Abc in any case. Add #include <stdio.h> at the beginning of your code, and it should work fine, assuming it does what you wanted it to do.
Again, this code
#include <stdio.h>
int main()
{
int j=97;
char arr[4]="Abc";
printf(arr,j);
return 0;
}
is a strange, but perfectly valid C program with a perfectly defined output (adding \n at the end of the output would be a good idea though).
In your line int i, a[i]; in the corrected sample of broken code, a is a variable-length array of i elements, but i is uninitialized. Thus your program has undefined behavior.
You see strings in C language are treated as char* and printf function can print a string directly. For printing strings using this function you should use such code:
printf("%s", arr);
%s tells the function that the first variable will be char*.
If you want to print both arr and j you should define the format first:
printf("%s%d", arr, j);
%d tells the function that the second variable will be int
I suspect the printf() issue is a red herring, since with a null-terminated "Abc" will ignore other arguments.
Have you debugged your program? If not can you be sure the fault isn't in getch()?
I cannot duplicate your issue but then I commented out the getch() for simplicity.
BTW, why did you not use fgetc() or getchar()? Are you intending to use curses in a larger program?
===== Added after your edit =====
Okay, not a red herring, just a mistake by the OP.
C++ does allow allocating an array with the size specified by a variable; you've essentially done this with random (garbage) size and overflowed the stack, as you deduced. When you compile with C++ you are typically no longer compiling C and the rules change (depending on the particular compiler).
That said, I don't understand your question - you need to be a lot more clear with "when we take size of array through user input" ...