473,394 Members | 1,841 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,394 software developers and data experts.

label inside for-loop

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>>

Nov 14 '05 #1
10 2755
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>>

Nov 14 '05 #2
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
Nov 14 '05 #3
boa
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]
Nov 14 '05 #4
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>>

Nov 14 '05 #5
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>>

Nov 14 '05 #6
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 vi************@whitehouse.gov
Nov 14 '05 #7
# 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.
Nov 14 '05 #8
Capstar <ne**@deleg.homeip.net> wrote in message news:<ca**********@news.tudelft.nl>...
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
mf*****@sbcglobal.net
Nov 14 '05 #9
In article <news:ca**********@news.tudelft.nl>
Capstar <ne**@deleg.homeip.net> 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.
Nov 14 '05 #10
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?
Since free(NULL) does nothing, you could do:

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

err_malloc_foo:
free(array[i]); }

return EXIT_FAILURE;
}


Alternatively:

struct foo
{
char *bar, *baz;
};

int main(void)
{
int i;
struct foo* array[6];
for (i=0; i<6; ++i)
{
if (!(array[i] = malloc(sizeof array[i])))
break;
if (!(array[i].bar = malloc(1024)))
break;
if (!(array[i].baz = malloc(256)))
break;
}
if (i == 6)
return EXIT_SUCCESS;

if (!array[i]) --i;
for (; i>=0; free(array[i--]))
{
/* check in the same order as allocation */
/* when we hit a NULL, the rest are unallocated */
if (!array[i].bar) continue;
free(array[i].bar);
if (!array[i].baz) continue;
free(array[i].baz);
}
return EXIT_FAILURE;
}

Or you could have a second variable that you set to 0 at the start of
the alloc loop and increment at each step. On failure, do a nasty
duff-esque switch/for:

int main(void)
{
int i,fail_step;
struct foo* array[6];
for (i=0; i<6; ++i)
{
fail_step = 0;
if (!(array[i] = malloc(sizeof array[i])))
break;
++fail_step;
if (!(array[i].bar = malloc(1024)))
break;
++fail_step;
if (!(array[i].baz = malloc(256)))
break;
}
if (i == 6)
return EXIT_SUCCESS;

switch (fail_step)
{
for (; i>=0; --i)
{
/* needs to be in reverse of alloc order */
case 2: free(array[i].baz]);
case 1: free(array[i].bar]);
case 0: free(array[i]);
}
}
return EXIT_FAILURE;
}

but I dunno if that's really any better than goto. (it'd really suck to
add a step in the middle...)

-josh

Nov 14 '05 #11

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

Similar topics

2
by: Spartanicus | last post by:
Is this correct usage of <label>?: <h5><label for="sp-q"><img src="search.png" alt="Search"></label></h5> <form method="get" action="http://search.atomz.com/search/"> <div> <input name="sp-q"...
2
by: Hareth | last post by:
i got the idea "form.textbox.text = label.text" from vb... i tried it in C# but it generated errors i found a diff example from :...
0
by: nevin | last post by:
I have a TreeView control which I progmatically (is that a word?) add a node to the root node BeginEdit() on that node and then want the user to change the name of it. Exactly as what happens when...
3
by: Josef K. | last post by:
Asp.net generates the following html when producing RadioButton lists: <td><input id="RadioButtonList_3" type="radio" name="MyRadioButtonList" value="644"...
6
by: jcrouse | last post by:
I am rotating some text is some label controls. In the one place I use it it works fine. In the other place I use it I can't figure out the syntax. I don't really understand the event. Where it...
4
by: Christian Hofmann | last post by:
Hello, How is it possible to use a hyperlink webcontrol inside a label webcontrol? I am using resources for globalisation. Now I have a text like this: Please click here to open that...
0
by: CharlesA | last post by:
Hi folks, I'm using ASP.net 1.1 with C# I've got this kind of thing going <div class="row"> <label class="col1">Rm Name</label> <asp:textbox id="txtRM" runat="server" cssclass="col2"...
14
by: subramanian100in | last post by:
Consider the following program: #include <iostream> using namespace std; int main() { int i;
5
by: SuneR | last post by:
Hi, I am having problems figuring out how to make Firefox behave, and output the HTML I want it to output. The thing I want done is actually quite simple. I have a <labeltag, and inside it, I...
9
by: =?Utf-8?B?RnJhbmsgVXJheQ==?= | last post by:
Hi all I have a MDI Container Form, with one label control on the Background of this container form. When I now open a child form, this form is behind the label ... and this looks ugly ... :-))...
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: 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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.