473,386 Members | 1,706 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

about the array

I'm confused about the VARIABLE LENGTH ARRAYS.
{scanf("%d",&n);float a[n];}
In which compiler can I use it?
I tried VC++6.0 SP6,but it's reported error:CONSTANT EXPRESSION!

Another question,
What the differences between:
(1)ElemType array[N]
(2)array=(ElemType*)malloc(N*size of(ElemType))
or array=(ElemType*)calloc(N,size of(ElemType))
<Of course,you can change the N in (2) into a VAR>
I just think they're almost the same.But...ther must be some
differences,not just the type of writting...
(By the way,my English is not very good.I hope that the above have
expressed my ideas without confusions!)
Thank you!谢谢(In Chinese)

Feb 28 '06 #1
7 2169
"Yuri_ÎàØÙ" <yu*******@126.com> writes:
I'm confused about the VARIABLE LENGTH ARRAYS.
{scanf("%d",&n);float a[n];}
In which compiler can I use it?
I tried VC++6.0 SP6,but it's reported error:CONSTANT EXPRESSION!
Variable length arrays are a new feature in C99; the earlier C90
standard doesn't support them. gcc supports them; apparently
your compiler doesn't.
Another question,
What the differences between:
(1)ElemType array[N]
(2)array=(ElemType*)malloc(N*size of(ElemType))
or array=(ElemType*)calloc(N,size of(ElemType))


You declared "array" as an array. malloc() and calloc() both returns
a pointer values, so your code is illegal. (You may have heard that
arrays are really pointers in C; they're not.) See section 6 of the
comp.lang.c FAQ, <http://www.c-faq.com/>.

Here's a legal version of what you wrote:

ElemType *ptr;
ptr = malloc(N * sizeof(ElemType));
/* or */
ptr = calloc(N, sizeof(ElemType));

The difference is that calloc initializes the allocated memory to
all-bits-zero. This is not as useful as you might think;
floating-point 0.0 and null pointer values aren't necessarily
represented as all-bits-zero.

Note: you should never cast the result of malloc() or calloc(). Doing
so can mask errors. Make sure you have a "#include <stdlib.h>".
Also, the following is actually less error-prone than what I wrote
above:

ElemType *ptr;
ptr = malloc(N * sizeof *ptr);
/* or */
ptr = calloc(N, sizeof *ptr);

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 28 '06 #2
Hello Keith,

"Note: you should never cast the result of malloc() or calloc(). Doing

so can mask errors."

AFAIK both them return void pointers which must be casted appropiately
before assigning.

Why should we never cast them and if we do what errors can come.

Regards,
Rajesh

Feb 28 '06 #3
Rajesh wrote:
Hello Keith,

"Note: you should never cast the result of malloc() or calloc(). Doing
so can mask errors."

AFAIK both them return void pointers
Yes.
which must be casted appropiately before assigning.
No. The whole point of void * in C is that it (generally) doesn't
need to be cast to other pointer types.
Why should we never cast them and if we do what errors can come.


http://benpfaff.org/writings/clc/malloc-cast.html.

--
Peter

Feb 28 '06 #4
Hello Peter,

Thanks for the explanations.

Can u put some light on :

"Casting its return value can mask a failure to #include <stdlib.h>,
which leads to undefined behavior"

What type of failure is it?

"C99 requires all functions to be declared before they are called."

Does C89 doesn't requires that?

Rajesh

Feb 28 '06 #5
"Rajesh" <ra***********@gmail.com> writes:
Can u put some light on :

"Casting its return value can mask a failure to #include <stdlib.h>,
which leads to undefined behavior"

What type of failure is it?

"C99 requires all functions to be declared before they are called."

Does C89 doesn't requires that?


Please read <http://cfaj.freeshell.org/google/>. Google is giving you
a badly distorted view of Usenet; that web page explains how to work
around it.

Please don't use abbreviations like "u" for "you". They make it much
more difficult to read what you write.

C89/C90 allows functions to be called without a visible declaration,
though it's a very bad idea. An undeclared function is assumed to
return int and take an unknown number and type of arguments. So, for
example, given:

void *ptr;
ptr = malloc(100);

if the declaration of malloc() isn't visible, the compiler assumes
(incorrectly) that it returns int, and you'll get a warning about a
type mismatch, attempting to assign an int to a void*. If you
give in to temptation and use a cast:

void *ptr;
ptr = (void*)malloc(100);

you haven't fixed the problem. The compiler *still* incorrectly
assumes that malloc() returns an int; you've told it to convert that
bogus int to void*. The result of the conversion won't necessarily be
the void* value that malloc() *tried* to return. This invokes
undefined behavior, which means anything can happen; it can work
correctly, it can crash your program, or (as the standard joke here
goes), it can make demons fly out of your nose.

So drop the cast and add the required "#include <stdlib.h>", and
everything works consistently. (And don't forget to check the result
of malloc(); if it fails, it returns a null pointer.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 28 '06 #6
Rajesh wrote:
Hello Peter,

Thanks for the explanations.

Can u put some light on :

"Casting its return value can mask a failure to #include <stdlib.h>,
which leads to undefined behavior"

What type of failure is it?

"C99 requires all functions to be declared before they are called."

Does C89 doesn't requires that?

Rajesh
What type of failure is it?


Disclaimer:

I guess the bottom line is - if the cast isn't necessary, why do it, esp. if
there exists some compiler, in the set of all compilers, that will screw up
if you do!

---

Taking the reasons from the webpage cited ...

1- The cast is not required in ANSI C.

2- Casting its return value can mask a failure to #include <stdlib.h>, which
leads to undefined behavior. As C99 slows[sic] becomes more popular, this
will become less of an issue, because C99 requires all functions to be
declared before they are called.

3- If you cast to the wrong type by accident, odd failures can result. This
is especially true if <stdlib.h> is not #included, as above, but alignment
can still cause trouble on particularly odd systems.

1. True - see the disclaimer.

2. IMHO, not likely ... in so far that if you used another function declared
in stdlib, you'd most likely get a warning about *its* use [unless it obeys
the default rules - in which case it's ok] - even if you somehow managed to
escape such a warning about misusing malloc. Esp. not likely to be an issue
when it's mandatory to have declared a function before using it of course.

3.

I think the argument is that *if* you cast wrongly, you could end up in
trouble. E.g., say you had this ...

char * p = (char)malloc(10);

Maybe p will only get CHAR_BIT's worth of data assigned to it [which you
probably don't want right]?

By including stdlib, the compiler should issue a diagnostic - gcc gives:
'cast from pointer to integer of different size'.

However, if you cast \correctly\, but omit stdlib, then the compiler may
make assumptions about what malloc \is\ [how to call/return a value from
it], and screw up, e.g., without the declaration, the compiler *should*
consider malloc to have external linkage, take an unknown set of arguments,
and return an int. So, if you have this usage - which is legal according to
those rules ...

void * p = (void *)malloc(10);

Well, maybe the int taken [off the stack or wherever it comes from] by the
compiler isn't *right* for a void *.

*However*, that all said, in my experience, compilers will typically tell
you that you haven't declared malloc before using it - with/without the
cast. For example, if you have either of these in gcc code ...

char * p = (char *)malloc(10);
char * p = (char)malloc(10);

You'll see warnings like this ...

"implicit declaration of function 'malloc'"
"incompatible implicit declaration of built-in function 'malloc'"
"cast from pointer to integer of different size"
"assignment makes pointer from integer without a cast"

So, if you then include stdlib, the second of those usages [the cast to
(char)] will once again cause gcc to issue the pointer to integer warning
again.

IMHO, most modern compilers would catch misuses, even if the sizes of a void
* and the lvalue are the same - but of diferent types. For example:

If an int is the same size as a void *, and you have this, and no #include
<stdlib.h> ...

int * p = (int)malloc(10);

Most compilers will complain along these lines ...

"assignment makes pointer from integer without a cast"

How about if you do this - where you're casting the return type to the
lvalue type ...

int p = (int)malloc(10);

"implicit declaration of function 'malloc'"
"incompatible implicit declaration of built-in function 'malloc'"

Re gcc, the 'built-in' part of this is interesting - because gcc obviously
*knows* about malloc, as demonstrated by, say, doing this [With *no* headers
included]:

int p;

p = (int)malloc();

gcc says:

"too few arguments to function 'malloc'"

So, switching to another - less smart - compiler, I get this:

'malloc' undefined; assuming extern returning int

And - to another - I get this :

Missing prototype for 'malloc'

So, in summary - IMHO

1. True - don't cast.
2. Hmmm.
3. if there exists some compiler, in the set of ... You can bet there is
more than one of course!
--
==============
Not a pedant
==============
Feb 28 '06 #7
pemo wrote:
Taking the reasons from the webpage cited ... [i.e. <http://benpfaff.org/writings/clc/malloc-cast.html>]
1- The cast is not required in ANSI C.

2- Casting its return value can mask a failure to #include <stdlib.h>,
which leads to undefined behavior. As C99 slows[sic] becomes more
popular, this will become less of an issue, because C99 requires all
functions to be declared before they are called.

3- If you cast to the wrong type by accident, odd failures can result.
This is especially true if <stdlib.h> is not #included, as above, but
alignment can still cause trouble on particularly odd systems.

1. True - see the disclaimer.

2. IMHO, not likely ... in so far that if you used another function
declared in stdlib, you'd most likely get a warning about *its* use
Quite often in my code, the _only_ functions being used from <stdlib.h>
are malloc and free. I don't always use the NULL macro, but when I do
it's often available from other headers (e.g. <stdio.h>.)

A call to an implicitly declared free() does not require a diagnostic.
[unless it obeys the default rules - in which case it's ok] - even
if you somehow managed to escape such a warning about misusing
malloc. Esp. not likely to be an issue when it's mandatory to have
declared a function before using it of course.
It isn't mandatory in C90! That's the whole point!!

Personally, I think it's fair to say that most compiler writers
appreciate the problems with using undeclared functions, so most
compilers will issue a diagnostic, but the C90 language itself
does not _require_ compilers to do so. [And there are plenty of
old compilers that won't issue a warning, let alone an error.]
3.

I think the argument is that *if* you cast wrongly, you could end up
in trouble. E.g., say you had this ...

char * p = (char)malloc(10);
That requires a diagnostic too because you're assigning an integer
value to a pointer without a cast (from int to pointer.) To be honest,
I'm not exactly sure what Ben is talking about in point 3.
Maybe p will only get CHAR_BIT's worth of data assigned to it [which
you probably don't want right]?

By including stdlib, the compiler should issue a diagnostic - gcc
gives: 'cast from pointer to integer of different size'.
Yes, it's a _required_ diagnostic, so _every_ conforming compiler
must issue a warning or error.
However, if you cast \correctly\, but omit stdlib, then the compiler
may make assumptions about what malloc \is\ [how to call/return a
value from it], and screw up, e.g., without the declaration, the
compiler *should* consider malloc to have external linkage, take an
unknown set of arguments, and return an int. So, if you have this
usage - which is legal according to those rules ...

void * p = (void *)malloc(10);
It is not legal since malloc returns a void *, not an int. The code
is no different to...

/* no #include <stdlib.h> */
int malloc();

void foo()
{
/* UB since malloc has the wrong signature */
void *p = (void *) malloc(10);
...
Well, maybe the int taken [off the stack or wherever it comes from]
by the compiler isn't *right* for a void *.
Indeed. It may be the wrong size, or may be in a completely different
register. [For example, Motorola's 68000 series has both data and
address registers. Many implementations will return an int in register
D0, and a pointer in register A0. Without a valid declaration, a
compiler may assume malloc's return value is in D0, instead of A0.
Thus, it may use a garbage value totally unrelated to the malloc()
call.]
*However*, that all said, in my experience, compilers will typically
tell you that you haven't declared malloc before using it - with/
without the cast.
I agree, but the issue is not about what _most_ compilers will or
won't do. [Or what most programmers _should_ be doing: turn on the
warning if available.] It's about whether compilers are _required_
to issue diagnostics, be they warnings or errors.

<snip> If an int is the same size as a void *, and you have this, and no
#include <stdlib.h> ...

int * p = (int)malloc(10);

Most compilers will complain along these lines ...

"assignment makes pointer from integer without a cast"
Yes, but you clearly don't understand _why_ the compiler is
_required_ to issue the diagnostic. It's to do with assignment.
The situation is identical to...

int *p = 0xFFFE;

I don't think that even the regulars of clc would accuse newbies of
commonly casting malloc to int.
How about if you do this - where you're casting the return type to
the lvalue type ...

int p = (int)malloc(10);


This doesn't require a diagnostic, but you now have implementation
defined behaviour (if you include a prototype for malloc.) Any
subsequent conversion of that int to a void *, e.g. ...

void *vp = (void *) p;

....need _not_ yield the original pointer returned by malloc(),
irrespective of whether int is wider than void * or not.

--
Peter

Mar 5 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: J. Campbell | last post by:
I posted a question some time back about accessing a char array as an array of words. In order not to overrun the char array, I padded it with enough 0x00 bytes to ensure that when accessed as...
3
by: Joe C | last post by:
I have some code that performs bitwise operations on files. I'm trying to make the code portable on different endian systems. This is not work/school related...just trying to learn/understand. ...
5
by: Tony Johansson | last post by:
Hello experts! I have two class template below with names Array and CheckedArray. The class template CheckedArray is derived from the class template Array which is the base class This program...
3
by: J Wang | last post by:
Dear, could you tell me about the usage of "##" in preprossor give me some simple examples. thanks. I just got the example from "dissection C" as follows:
24
by: David Mathog | last post by:
If this: int i,sum; int *array; for(sum=0, i=0; i<len; i++){ sum += array; } is converted to this (never mind why for the moment):
13
by: agentxx04 | last post by:
Hi. Our assignment was to creat a program that can find the average, median & mode of a #of integers. Here's my program: #include<stdio.h> int main() { int item; int a, b, t, mode; int...
15
by: copx | last post by:
Q1: If an array is declared static in file A is it still valid to access it from file B? I mean if a function form file A which returns a pointer to a position inside of the array is called from...
14
by: ablock | last post by:
I have an array to which i have a added a method called contains. I would like to transverse this array using for...in...I understand fully that for...in is really meant for Objects and not Arrays,...
17
by: DiAvOl | last post by:
Hello everyone, merry christmas! I have some questions about the following program: arrtest.c ------------ #include <stdio.h> int main(int agc, char *argv) {
15
by: SM | last post by:
Hello, I have another simple question about an array in PHP and a variable in PHP. This is the array: $thumbs_cat_1 = array( 'wine', 'cheese', 'ice',
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.