Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > label inside for-loop

Reply
Thread Tools

label inside for-loop

 
 
Capstar
Guest
Posts: n/a
 
      06-08-2004
Hi NG,

I'm trying to allocate some resources, in this example a structure, with
containing a buffer. When a allocation failes, all previous allocations
need to be freed. When I try to compile it I get the next warning:

resource-loop.c:38: warning: deprecated use of label at end of compound
statement

Is there a better way of doing this?
Or is this guaranteed to work anyway?

#include <stdlib.h>
#include <stdio.h>

struct foo
{
char *bar;
};

int main(void)
{
int i;
struct foo* array[6];

for(i = 0; i < 6; ++i)
{
if(!(array[i] = malloc(sizeof *array[i])))
{
fprintf(stderr, "Unable to allocate foo%d\n", i);
goto err_malloc_foo;
}

if(!(array[i]->bar = malloc(1024)))
{
fprintf(stderr, "Unable to allocate bar%d\n", i);
goto err_malloc_bar;
}
}

return EXIT_SUCCESS;

for(; i >= 0; --i)
{
free(array[i]->bar);
err_malloc_bar:

free(array[i]);
err_malloc_foo:
}

return EXIT_FAILURE;
}


Mark

--
<<Remove the del for email>>

 
Reply With Quote
 
 
 
 
Capstar
Guest
Posts: n/a
 
      06-08-2004
Capstar wrote:
> Hi NG,
>
> I'm trying to allocate some resources, in this example a structure, with
> containing a buffer. When a allocation failes, all previous allocations
> need to be freed. When I try to compile it I get the next warning:
>
> resource-loop.c:38: warning: deprecated use of label at end of compound
> statement
>
> Is there a better way of doing this?
> Or is this guaranteed to work anyway?
>
> #include <stdlib.h>
> #include <stdio.h>
>
> struct foo
> {
> char *bar;
> };
>
> int main(void)
> {
> int i;
> struct foo* array[6];
>
> for(i = 0; i < 6; ++i)
> {
> if(!(array[i] = malloc(sizeof *array[i])))
> {
> fprintf(stderr, "Unable to allocate foo%d\n", i);
> goto err_malloc_foo;
> }
>
> if(!(array[i]->bar = malloc(1024)))
> {
> fprintf(stderr, "Unable to allocate bar%d\n", i);
> goto err_malloc_bar;
> }
> }
>
> return EXIT_SUCCESS;
>
> for(; i >= 0; --i)
> {
> free(array[i]->bar);
> err_malloc_bar:
>
> free(array[i]);
> err_malloc_foo:
> }
>
> return EXIT_FAILURE;
> }
>
>
> Mark
>


Ok, I just thought of another way of doing the last piece:

return EXIT_SUCCESS;

while(i >= 0)
{
free(array[i]->bar);
err_malloc_bar:

free(array[i]);
err_malloc_foo:

--i;
}

return EXIT_FAILURE;

The warning is gone now, which makes sence because the label is not at
the end of a compound statement anymore. But why does this make any
difference? It seems to me that functionally it didn't change at all.

Or am I missing something here?

Mark

--
<<Remove the del for email>>

 
Reply With Quote
 
 
 
 
Harti Brandt
Guest
Posts: n/a
 
      06-08-2004
On Tue, 8 Jun 2004, Capstar wrote:

C>Capstar wrote:
C>> Hi NG,
C>>
C>> I'm trying to allocate some resources, in this example a structure, with
C>> containing a buffer. When a allocation failes, all previous allocations need
C>> to be freed. When I try to compile it I get the next warning:
C>>
C>> resource-loop.c:38: warning: deprecated use of label at end of compound
C>> statement
C>>
C>> Is there a better way of doing this?
C>> Or is this guaranteed to work anyway?
C>>
C>> #include <stdlib.h>
C>> #include <stdio.h>
C>>
C>> struct foo
C>> {
C>> char *bar;
C>> };
C>>
C>> int main(void)
C>> {
C>> int i;
C>> struct foo* array[6];
C>>
C>> for(i = 0; i < 6; ++i)
C>> {
C>> if(!(array[i] = malloc(sizeof *array[i])))
C>> {
C>> fprintf(stderr, "Unable to allocate foo%d\n", i);
C>> goto err_malloc_foo;
C>> }
C>>
C>> if(!(array[i]->bar = malloc(1024)))
C>> {
C>> fprintf(stderr, "Unable to allocate bar%d\n", i);
C>> goto err_malloc_bar;
C>> }
C>> }
C>>
C>> return EXIT_SUCCESS;
C>>
C>> for(; i >= 0; --i)
C>> {
C>> free(array[i]->bar);
C>> err_malloc_bar:
C>>
C>> free(array[i]);
C>> err_malloc_foo:
C>> }
C>>
C>> return EXIT_FAILURE;
C>> }
C>>
C>>
C>> Mark
C>>
C>
C>Ok, I just thought of another way of doing the last piece:
C>
C> return EXIT_SUCCESS;
C>
C> while(i >= 0)
C> {
C> free(array[i]->bar);
C>err_malloc_bar:
C>
C> free(array[i]);
C>err_malloc_foo:
C>
C> --i;
C> }
C>
C> return EXIT_FAILURE;
C>
C>The warning is gone now, which makes sence because the label is not at the end
C>of a compound statement anymore. But why does this make any difference? It
C>seems to me that functionally it didn't change at all.
C>
C>Or am I missing something here?

A label always stands before a statement. If you need a label at the end
of a compound just put a null-statement after the label:

foo: ;

harti
 
Reply With Quote
 
boa
Guest
Posts: n/a
 
      06-08-2004
Capstar wrote:
> Capstar wrote:
>
>> Hi NG,
>>
>> I'm trying to allocate some resources, in this example a structure,
>> with containing a buffer. When a allocation failes, all previous
>> allocations need to be freed. When I try to compile it I get the next
>> warning:
>>
>> resource-loop.c:38: warning: deprecated use of label at end of
>> compound statement
>>
>> Is there a better way of doing this?


Maybe, how about this version? It has no goto's and has fewer calls to
malloc, hopefully leading to faster code and less fragmented memory.

#include <stdlib.h>
#include <stdio.h>

struct foo {
char *bar;
};

#define NELEM 6

int main(void)
{
int i;
struct foo* array;

if( (array = malloc(sizeof *array * NELEM)) == NULL)
return EXIT_FAILURE;

for(i = 0; i < NELEM; i++) {
if( (array[i].bar = malloc(1024)) == NULL) {
while(--i >= 0)
free(array[i].bar);
free(array);
return EXIT_FAILURE;
}
}

return EXIT_SUCCESS;
}


HTH,
boa
[snip]
 
Reply With Quote
 
Capstar
Guest
Posts: n/a
 
      06-08-2004
boa wrote:
> Capstar wrote:
>
>> Capstar wrote:
>>
>>> Hi NG,
>>>
>>> I'm trying to allocate some resources, in this example a structure,
>>> with containing a buffer. When a allocation failes, all previous
>>> allocations need to be freed. When I try to compile it I get the next
>>> warning:
>>>
>>> resource-loop.c:38: warning: deprecated use of label at end of
>>> compound statement
>>>
>>> Is there a better way of doing this?

>
>
> Maybe, how about this version? It has no goto's and has fewer calls to
> malloc, hopefully leading to faster code and less fragmented memory.
>
> #include <stdlib.h>
> #include <stdio.h>
>
> struct foo {
> char *bar;
> };
>
> #define NELEM 6
>
> int main(void)
> {
> int i;
> struct foo* array;
>
> if( (array = malloc(sizeof *array * NELEM)) == NULL)
> return EXIT_FAILURE;
>
> for(i = 0; i < NELEM; i++) {
> if( (array[i].bar = malloc(1024)) == NULL) {
> while(--i >= 0)
> free(array[i].bar);
> free(array);
> return EXIT_FAILURE;
> }
> }
>
> return EXIT_SUCCESS;
> }
>


This is about how I would normally do this, but this was just some
example code. The actual code is part of the initialisation code for a
device driver. So there are lots of calls, which can fail. And if one
fails all previous calls that allocate or register stuff need to be
undone. That can offcourse be done without any goto's but, but That
would mean lots of nested if-else statements, and make my code complete
unreadable. This loop thing is ment for requesting some pci space and
mapping it to virtual memory space. In my previous version I just copied
the code 6 times. So this was actually an effort to clean things up a bit.

But thanks for your input anyway.

Mark
--
<<Remove the del for email>>

 
Reply With Quote
 
Capstar
Guest
Posts: n/a
 
      06-08-2004
Harti Brandt wrote:
> On Tue, 8 Jun 2004, Capstar wrote:
>
> C>Capstar wrote:
> C>> Hi NG,
> C>>
> C>> I'm trying to allocate some resources, in this example a structure, with
> C>> containing a buffer. When a allocation failes, all previous allocations need
> C>> to be freed. When I try to compile it I get the next warning:
> C>>
> C>> resource-loop.c:38: warning: deprecated use of label at end of compound
> C>> statement
> C>>
> C>> Is there a better way of doing this?
> C>> Or is this guaranteed to work anyway?
> C>>
> C>> #include <stdlib.h>
> C>> #include <stdio.h>
> C>>
> C>> struct foo
> C>> {
> C>> char *bar;
> C>> };
> C>>
> C>> int main(void)
> C>> {
> C>> int i;
> C>> struct foo* array[6];
> C>>
> C>> for(i = 0; i < 6; ++i)
> C>> {
> C>> if(!(array[i] = malloc(sizeof *array[i])))
> C>> {
> C>> fprintf(stderr, "Unable to allocate foo%d\n", i);
> C>> goto err_malloc_foo;
> C>> }
> C>>
> C>> if(!(array[i]->bar = malloc(1024)))
> C>> {
> C>> fprintf(stderr, "Unable to allocate bar%d\n", i);
> C>> goto err_malloc_bar;
> C>> }
> C>> }
> C>>
> C>> return EXIT_SUCCESS;
> C>>
> C>> for(; i >= 0; --i)
> C>> {
> C>> free(array[i]->bar);
> C>> err_malloc_bar:
> C>>
> C>> free(array[i]);
> C>> err_malloc_foo:
> C>> }
> C>>
> C>> return EXIT_FAILURE;
> C>> }
> C>>
> C>>
> C>> Mark
> C>>
> C>
> C>Ok, I just thought of another way of doing the last piece:
> C>
> C> return EXIT_SUCCESS;
> C>
> C> while(i >= 0)
> C> {
> C> free(array[i]->bar);
> C>err_malloc_bar:
> C>
> C> free(array[i]);
> C>err_malloc_foo:
> C>
> C> --i;
> C> }
> C>
> C> return EXIT_FAILURE;
> C>
> C>The warning is gone now, which makes sence because the label is not at the end
> C>of a compound statement anymore. But why does this make any difference? It
> C>seems to me that functionally it didn't change at all.
> C>
> C>Or am I missing something here?
>
> A label always stands before a statement. If you need a label at the end
> of a compound just put a null-statement after the label:
>
> foo: ;
>


Thanks, that did the trick.

After opening a book after reading this, I found out that a goto points
to a 'labelled statement', and not to just a 'label' as I used to think.

Never to old to learn
--
<<Remove the del for email>>

 
Reply With Quote
 
Darrell Grainger
Guest
Posts: n/a
 
      06-08-2004
On Tue, 8 Jun 2004, Capstar wrote:

> Hi NG,
>
> I'm trying to allocate some resources, in this example a structure, with
> containing a buffer. When a allocation failes, all previous allocations
> need to be freed. When I try to compile it I get the next warning:
>
> resource-loop.c:38: warning: deprecated use of label at end of compound
> statement
>
> Is there a better way of doing this?


Allocate one large block of memory and initialize the pointers so they
point into that one large block. One call to malloc, one call to free.

> Or is this guaranteed to work anyway?
>
> #include <stdlib.h>
> #include <stdio.h>
>
> struct foo
> {
> char *bar;
> };
>
> int main(void)
> {
> int i;
> struct foo* array[6];
>
> for(i = 0; i < 6; ++i)
> {
> if(!(array[i] = malloc(sizeof *array[i])))
> {
> fprintf(stderr, "Unable to allocate foo%d\n", i);
> goto err_malloc_foo;
> }
>
> if(!(array[i]->bar = malloc(1024)))
> {
> fprintf(stderr, "Unable to allocate bar%d\n", i);
> goto err_malloc_bar;
> }
> }
>
> return EXIT_SUCCESS;
>
> for(; i >= 0; --i)
> {
> free(array[i]->bar);
> err_malloc_bar:
>
> free(array[i]);
> err_malloc_foo:
> }
>
> return EXIT_FAILURE;
> }
>
>
> Mark
>
> --
> <<Remove the del for email>>
>
>


--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to
 
Reply With Quote
 
SM Ryan
Guest
Posts: n/a
 
      06-08-2004
# resource-loop.c:38: warning: deprecated use of label at end of compound
# statement

Use an empty statement.

# free(array[i]);
# err_malloc_foo:
# }

free(array[i]);
err_malloc_foo:
;
}

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Title does not dictate behaviour.
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      06-08-2004
In article <news:ca3vu4$rbh$>
Capstar <> writes:

[ "goto label; ... { ... label: }" produces the complaint ]

>resource-loop.c:38: warning: deprecated use of label at end of compound
>statement


As others have noted, the immediate fix is to use a null statement.

It is worth pointing out that what is "deprecated" here is actually
a GNUC extension -- the syntax above has always been invalid in
ANSI C. The GCC folks decided to allow it, and have now decided
to stop allowing it.

For those who want to find one, there is a moral in here about
depending on compiler-specific extensions.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
Mark F. Haigh
Guest
Posts: n/a
 
      06-08-2004
Capstar <> wrote in message news:<ca3vu4$rbh$>...
> Hi NG,
>
> I'm trying to allocate some resources, in this example a structure, with
> containing a buffer. When a allocation failes, all previous allocations
> need to be freed. When I try to compile it I get the next warning:
>
> resource-loop.c:38: warning: deprecated use of label at end of compound
> statement
>


Look at the following section in the C99 standard:

A.2.3 Statements

(6.8.1) labeled-statement:
identifier : statement
case constant-expression : statement
default : statement

You'll notice that a label does not stand alone; rather, it's labeling
a statement. What's prompting the warning from the compiler is that
you're labeling the closing bracket.

Instead, simply label an empty statement like:

<snip>
> for(; i >= 0; --i)
> {
> free(array[i]->bar);
> err_malloc_bar:
>
> free(array[i]);
> err_malloc_foo:

; /* empty statement */
> }
>
> return EXIT_FAILURE;
> }



Mark F. Haigh

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[cpp] using expressions inside a #define label Andrey Vul C Programming 2 10-24-2009 12:10 AM
break inside of case- statement inside of loop Alexander Korsunsky C Programming 25 02-27-2007 04:39 AM
Radio Button Loop inside Form Element Loop wreed Javascript 9 10-16-2006 01:39 PM
Loop Inside loop for writing text lines Aggelos ASP General 2 11-12-2003 08:59 AM
accessing an asp:label from inside a .dll Will ASP .Net 1 08-13-2003 03:13 AM



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57