When I compile the program below "Program start" with
gcc -std=c99 -pedantic -o bgcc bgcc.c
(where gcc --version gives
gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
Copyright (C) 2004 Free Software Foundation, Inc.
)
I get the warning
bgcc.c:3: warning: "struct thingTag" declared inside parameter list
bgcc.c:3: warning: its scope is only this definition or declaration, which
is probably not what you want
Should the code generate a warning? Is there a way to avoid it other than
adding
typedef struct thingTag * thingP;
and replacing line 3 with
typedef void (*show)( thingP);
(which does shut gcc up)?
TIA
Duncan
Program start
#include <stdio.h>
typedef void (*show)( struct thingTag *);
typedef struct thingTag
{ show f;
double v;
} thing;
void show_metres( thing* p)
{ printf( "%f m\n", p->v);
}
int main( int argc, char** argv)
{
thing T;
T.v = 1.7;
T.f = show_metres;
T.f( &T);
return 1;
} 10 2107
Why not just do this:
#include <stdio.h>
typedef struct thingTag thing;
typedef void (*show)( thing *);
struct thingTag
{ show f;
double v;
};
void show_metres( thing* p)
{ printf( "%f m\n", p->v);
}
int main( int argc, char** argv)
{
thing T;
T.v = 1.7;
T.f = show_metres;
T.f( &T);
return 1;
}
Duncan Muirhead said:
<snip> Should the code generate a warning?
<snip>
Program start #include <stdio.h>
Add a forward declaration here:
struct thingTag;
typedef void (*show)( struct thingTag *);
typedef struct thingTag {show f; double v; } thing;
That should shut it up.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Duncan Muirhead <no***@this.add ress> writes: When I compile the program below "Program start" with gcc -std=c99 -pedantic -o bgcc bgcc.c (where gcc --version gives gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2) Copyright (C) 2004 Free Software Foundation, Inc. ) I get the warning bgcc.c:3: warning: "struct thingTag" declared inside parameter list bgcc.c:3: warning: its scope is only this definition or declaration, which is probably not what you want
Should the code generate a warning? Is there a way to avoid it other than adding typedef struct thingTag * thingP; and replacing line 3 with typedef void (*show)( thingP); (which does shut gcc up)?
TIA Duncan
Program start #include <stdio.h>
/* HERE */
typedef void (*show)( struct thingTag *);
At this point, the compiler hasn't seen "struct thingTag". It doesn't
know that you're going to declare it later.
You can add an incomplete type declaration before the typedef, at the
point marked /* HERE */ above:
struct thingTag;
typedef struct thingTag { show f; double v; } thing;
void show_metres( thing* p) { printf( "%f m\n", p->v); }
int main( int argc, char** argv) { thing T; T.v = 1.7; T.f = show_metres; T.f( &T); return 1;
Why are you returning 1 from your main program? The only portably
defined results are 0, EXIT_SUCCESS, and EXIT_FAILURE. On many
systems (but not all), "return 1;" from main() indicates a failure.
}
Incidentally, there's no real benefit in creating a typedef for a
structure type. It merely creates an alias "thing" for something that
already has a perfectly good name, "struct thingTag" -- and its an
alias that can't be used as flexibly as the original name.
Here's how I'd probably write it:
=============== =============== ==========
#include <stdio.h>
struct thing;
typedef void (*show)( struct thing *);
struct thing {
show f;
double v;
};
void show_metres(str uct thing* p)
{
printf("%f m\n", p->v);
}
int main(int argc, char** argv)
{
struct thing T;
T.v = 1.7;
T.f = show_metres;
T.f( &T);
return 0;
}
=============== =============== ==========
Though I might be tempted to drop the other typedef as well and write
it like this:
=============== =============== ==========
#include <stdio.h>
struct thing {
void (*f)(struct thing *);
double v;
};
void show_metres(str uct thing* p)
{
printf("%f m\n", p->v);
}
int main(int argc, char** argv)
{
struct thing T;
T.v = 1.7;
T.f = show_metres;
T.f( &T);
return 0;
}
=============== =============== ==========
--
Keith Thompson (The_Other_Keit h) 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.
Duncan Muirhead wrote: When I compile the program below "Program start" with gcc -std=c99 -pedantic -o bgcc bgcc.c (where gcc --version gives gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2) Copyright (C) 2004 Free Software Foundation, Inc. ) I get the warning bgcc.c:3: warning: "struct thingTag" declared inside parameter list bgcc.c:3: warning: its scope is only this definition or declaration, which is probably not what you want
Should the code generate a warning?
The code is invalid and a diagnostic is required. The warning you
quoted is not required, but tells you exactly what you're doing wrong.
Is there a way to avoid it other than adding typedef struct thingTag * thingP; and replacing line 3 with typedef void (*show)( thingP); (which does shut gcc up)?
Any way you fix it, you'll have to declare struct thingTag once before
you reference it in show's parameter list. It can be as simple as a
"struct thingTag;" on line 2.
#include <stdio.h>
typedef void (*show)( struct thingTag *);
Here you declare one struct thingTag (let's call it struct A), but its
declaration is only the scope of show's parameter list, which is not
what you want. Your compiler gave a very helpful error message, but you
decided to ignore it. Why?
typedef struct thingTag
Since the original struct thingTag went out of scope, here you declare
(and define) a completely different struct thingTag. Let's call it
struct B.
{ show f;
This is still a pointer to a function taking struct A.
double v; } thing;
void show_metres( thing* p) { printf( "%f m\n", p->v); }
int main( int argc, char** argv) { thing T; T.v = 1.7; T.f = show_metres;
This line requires a diagnostic. show_metres is a function taking a
pointer to struct B, and T.f requires a pointer to a function taking
struct A. They are different, and there is no implicit conversion
between them in standard C.
T.f( &T);
This line requires a diagnostic. T.f is a pointer to a function taking
a pointer to struct A, and you pass it a pointer to struct B. They are
different, and there is no implicit conversion between them in standard
C.
return 1;
This may exit successfully on some implementations , unsuccessfully on
others, and perhaps even something in-between on yet more. Are you sure
you don't mean EXIT_FAILURE, or 0 or EXIT_SUCCESS ?
}
In article <pa************ *************** *@this.address>
Duncan Muirhead <no***@this.add ress> wrote: I get the warning bgcc.c:3: warning: "struct thingTag" declared inside parameter list bgcc.c:3: warning: its scope is only this definition or declaration, which is probably not what you want
See <http://groups.google.c om/gr************* *******@news2.n ewsguy.com>.
--
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.
On Tue, 20 Jun 2006 17:57:04 +0000, Keith Thompson wrote: Duncan Muirhead <no***@this.add ress> writes: When I compile the program below "Program start" with gcc -std=c99 -pedantic -o bgcc bgcc.c (where gcc --version gives gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2) Copyright (C) 2004 Free Software Foundation, Inc. ) I get the warning bgcc.c:3: warning: "struct thingTag" declared inside parameter list bgcc.c:3: warning: its scope is only this definition or declaration, which is probably not what you want
Should the code generate a warning? Is there a way to avoid it other than adding typedef struct thingTag * thingP; and replacing line 3 with typedef void (*show)( thingP); (which does shut gcc up)?
TIA Duncan
Program start #include <stdio.h>
/* HERE */
typedef void (*show)( struct thingTag *);
At this point, the compiler hasn't seen "struct thingTag". It doesn't know that you're going to declare it later.
You can add an incomplete type declaration before the typedef, at the point marked /* HERE */ above:
struct thingTag;
typedef struct thingTag { show f; double v; } thing;
void show_metres( thing* p) { printf( "%f m\n", p->v); }
int main( int argc, char** argv) { thing T; T.v = 1.7; T.f = show_metres; T.f( &T); return 1;
Why are you returning 1 from your main program? The only portably defined results are 0, EXIT_SUCCESS, and EXIT_FAILURE. On many systems (but not all), "return 1;" from main() indicates a failure.
}
Incidentally, there's no real benefit in creating a typedef for a structure type. It merely creates an alias "thing" for something that already has a perfectly good name, "struct thingTag" -- and its an alias that can't be used as flexibly as the original name.
Here's how I'd probably write it: =============== =============== ========== #include <stdio.h>
struct thing;
typedef void (*show)( struct thing *);
struct thing { show f; double v; };
void show_metres(str uct thing* p) { printf("%f m\n", p->v); }
int main(int argc, char** argv) { struct thing T; T.v = 1.7; T.f = show_metres; T.f( &T); return 0; } =============== =============== ==========
Though I might be tempted to drop the other typedef as well and write it like this: =============== =============== ========== #include <stdio.h>
struct thing { void (*f)(struct thing *); double v; };
void show_metres(str uct thing* p) { printf("%f m\n", p->v); }
int main(int argc, char** argv) { struct thing T; T.v = 1.7; T.f = show_metres; T.f( &T); return 0; } =============== =============== ==========
Thank you, all, for your replies. However I am still somewhat bemused.
If I alter the program by adding
typedef struct
{ struct thingTag* p;
} entity;
before the typedef for show, no warnings are generated. If I add it after
show, show (but not entity) generates warnings. Is this difference in
references to undeclared types in functions and structs an oddity of the
language or the compiler?
TIA
Duncan
Duncan Muirhead <no***@this.add ress> writes:
[...] Thank you, all, for your replies. However I am still somewhat bemused. If I alter the program by adding typedef struct { struct thingTag* p; } entity; before the typedef for show, no warnings are generated. If I add it after show, show (but not entity) generates warnings. Is this difference in references to undeclared types in functions and structs an oddity of the language or the compiler?
Please trim quoted material when you post a followup. Provide enough
context so we can understand what's going on; that seldom requires
quoting everything.
Here's the original (incorrect) program:
=============== =============== ==========
#include <stdio.h>
typedef void (*show)( struct thingTag *);
typedef struct thingTag
{ show f;
double v;
} thing;
void show_metres( thing* p)
{ printf( "%f m\n", p->v);
}
int main( int argc, char** argv)
{
thing T;
T.v = 1.7;
T.f = show_metres;
T.f( &T);
return 1;
}
=============== =============== ==========
The first occurrence of "struct thingTag" is inside the typedef for
"show". Since there's been no complete declaration of that type, the
compiler treats it as an implicit declaration of a new incomplete
type; normally, such an incomplete type would be completed later. But
in this case, the new incomplete type appears within a function
prototype, and its scope is limited to that prototype. It's just as
if you had declared, within a function:
{
struct incomplete_type ;
}
struct incomplete_type {
int x;
int y;
}
The scope of the incomplete declaration is limited to the
brace-enclosed block in which it appears. By the time we see the
complete declaration, the previous incomplete declaration no longer
exists.
When you add your
typedef struct
{ struct thingTag* p;
} entity;
*before* the "show" typedef, you mention "struct thingTag". This is
now treated as a new incomplete type, but since it's not inside the
prototype, its scope extends to the end of the file. (This is
incidental to the declaration of "entity".) Now the compiler sees the
occurrence of "struct thingTag" within the prototype in the "show"
typedef as a reference to the existing incomplete type, rather than as
an implicit declaration of a new one.
If you put the typedef for "entity" *after* the "show" typedef, then
the "struct thingTag" within the prototype declares a new incomplete
type with a limited scope, and the compile warns you about it (because
that's not a useful thing to do). The "struct thingTag" within the
typedef for "entity" *also* declares a new incomplete type (since the
"struct thingTag" from the prototype is out of scope and therefore
doesn't exist), but it's not of such limited scope, so the compiler
doesn't warn you about it.
(This whole business of something being a new declaration if and only
if the thing hasn't already been declared is, IMHO, unfortunate and
confusing, and can mask some serious errors, but there it is.)
If you need a forward declaration of a structure, just do it directly,
not as part of another declaration.
And again, you should seriously consider getting rid of any typedefs
for struct types. By having just one name for the type, you have
fewer things to keep track of.
--
Keith Thompson (The_Other_Keit h) 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.
On Wed, 21 Jun 2006 20:31:48 +0000, Keith Thompson wrote: Duncan Muirhead <no***@this.add ress> writes: [...]
[trimmed] The first occurrence of "struct thingTag" is inside the typedef for "show". Since there's been no complete declaration of that type, the compiler treats it as an implicit declaration of a new incomplete type; normally, such an incomplete type would be completed later. But in this case, the new incomplete type appears within a function prototype, and its scope is limited to that prototype. It's just as if you had declared, within a function:
{ struct incomplete_type ; } struct incomplete_type { int x; int y; }
The scope of the incomplete declaration is limited to the brace-enclosed block in which it appears. By the time we see the complete declaration, the previous incomplete declaration no longer exists.
When you add your
typedef struct { struct thingTag* p; } entity;
*before* the "show" typedef, you mention "struct thingTag". This is now treated as a new incomplete type, but since it's not inside the prototype, its scope extends to the end of the file. (This is incidental to the declaration of "entity".) Now the compiler sees the occurrence of "struct thingTag" within the prototype in the "show" typedef as a reference to the existing incomplete type, rather than as an implicit declaration of a new one.
If you put the typedef for "entity" *after* the "show" typedef, then the "struct thingTag" within the prototype declares a new incomplete type with a limited scope, and the compile warns you about it (because that's not a useful thing to do). The "struct thingTag" within the typedef for "entity" *also* declares a new incomplete type (since the "struct thingTag" from the prototype is out of scope and therefore doesn't exist), but it's not of such limited scope, so the compiler doesn't warn you about it.
(This whole business of something being a new declaration if and only if the thing hasn't already been declared is, IMHO, unfortunate and confusing, and can mask some serious errors, but there it is.)
If you need a forward declaration of a structure, just do it directly, not as part of another declaration.
And again, you should seriously consider getting rid of any typedefs for struct types. By having just one name for the type, you have fewer things to keep track of.
Thank you for your informative reply.
If I understand you correctly, there is a special rule for declarations
of function (pointer) types: any any reference to an undeclared type
declares a new (incomplete) type whose scope is limited to the declaration
of the function type. Within struct (and union) declarations the scope of
any new incomplete type is the file. While this seems unfortunate to me,
if that's the way it is, that's the way it is.
As for typedefs for struct types, I suspect your right, but would say:
I, and indeed the people I've worked with, only ever use the typedef'd
names in code and so having the two names is limited to the type
declaration.
Every now and again I've encountered cases where a struct type is changed
(usually to a primitive, very occasionally to a union). In these cases
were a typedef not used, more edits would have to be made -- though
admittedly they were safe edits in that the compiler reports errors for
any edits not done correctly.
Duncan
Duncan Muirhead <no***@this.add ress> writes:
[...] Thank you for your informative reply. If I understand you correctly, there is a special rule for declarations of function (pointer) types: any any reference to an undeclared type declares a new (incomplete) type whose scope is limited to the declaration of the function type. Within struct (and union) declarations the scope of any new incomplete type is the file. While this seems unfortunate to me, if that's the way it is, that's the way it is.
More or less.
An appearance of "struct foo" refers to an existing type "struct foo"
if it's been declared; otherwise it creates a new incomplete type.
Any declaration has a scope, depending on where it appears, and does
not exist outside that scope. A function prototype is a scope, so if
"struct foo" appears within a prototype, and there's no existing
visible declaration for "struct foo", then the new incomplete type
"struct foo" isn't visible past the end of the prototype. This is
almost certainly useless; thus the warning.
Scopes are explained in section 6.2.1 of the C99 standard; a free
version can be found by googling n1124.pdf.
There are four kinds of scopes: function, file, block, and function
prototype. (Function scope applies only to labels.)
As for typedefs for struct types, I suspect your right, but would say: I, and indeed the people I've worked with, only ever use the typedef'd names in code and so having the two names is limited to the type declaration.
Then I guess you're stuck with it. I find it cleaner to use just the
struct tag, but it's not worth wholesale re-writing of the code. (And
as I said, my opinion on this point is not shared by everyone.)
--
Keith Thompson (The_Other_Keit h) 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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Steven D'Aprano |
last post by:
I'm trying to keep an open mind, but I am perplexed
about something in Python that strikes me as a poor design.
py> def func(a,b):
py> print a,b
py> func(1)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: func() takes exactly 2 arguments (1 given)
|
by: GitarJake |
last post by:
Hello all,
Newbie here.
SQL 2000, Windows 2000
I'm trying to alter tables in my SQL DB using statements like the following:
/* AD_GROUPS */
alter table AD_GROUPS alter column AD_GROUP_NAME nvarchar(64)not null
go
|
by: Dilip |
last post by:
Vaclav
I have taken the liberty to cross-post this
microsoft.public.dotnet.languages.vc which has more visibility from
MSFT VC++ team.
thanks
--Dilip
Actual post by Vaclav Haisman originally posted at
|
by: Brad |
last post by:
I have written some code to manipulate data/records in a MASTER (order
header) and DETAIL (order details) tables.
What I have written is too extensive to post but essentially trying to:
1. Assign to a datarow (dr1) the first record of the MASTER table
2. Assign to another datarow (dr2) the second record of the MASTER table
3. If dr1.field1 = dr2.field1, then proceed, otherwise do stop
4. Assign to a third datarow (dr3) the first record...
|
by: Peter Ritchie |
last post by:
Does anyone know how to suppress a specific warning for a line or block of
code in C#? C++ has a nice facility to disable a warning for a block of code
with #pragma for warnings that are incorrect or don't apply.
For example, the following code generates an CS0628 because CS0628 makes an
incorrect assumption that "protected" applies only to inheritance:
public sealed class Class
{
EmbeddedClass utility = new EmbeddedClass();
| |
by: Sven |
last post by:
Hi,
I found a strange behaviour when using the time() function from time.h.
Sometimes when it is called, it does not show the correct time in
seconds, but an initial value. This time seem to be the time when the
program was started the first time.
My platform is a DEC machine with Tru64 onboard.
A possible explanation could be, that the time() function is called
|
by: Don Burden |
last post by:
We've started converting some applications to the .NET 2.0 framework. When
compiling in VS 2005, I'm getting a warning on this line:
return (unitWidth != null ) ? unitWidth : new Unit("0px");
Looks valid to me, but this gives a warning with "new" underlined saying
"warning CS0429: Unreachable expression code detected".
|
by: torpecool |
last post by:
Hello Everyone,
I have been trying to find information about this issue in the
documentation and have not been able to. I hope someone can help.
I built a web-based app (PHP) that allows users to upload the contents
of a CSV file into database tables.
My users have reported that most of the time, everything is fine, but
some records do not show up. Although I can see the records by doing
|
by: kepston |
last post by:
Hi
I have a report which splits invoice costs to various departments and shows a summary.
The various divisors and multipliers used in deriving the values for each department, are such that the final figures will not be to 2 decimal places.
I decided to use the Round() function so that the calculated figure would equal the formatted figure. I then Summed the rounded figures to reach a total.
Occasionally the sum will not equal the actual...
|
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |