Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #93474 > unrolled thread
| Started by | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| First post | 2016-09-14 12:01 -0700 |
| Last post | 2016-09-15 11:23 -0700 |
| Articles | 20 on this page of 99 — 14 participants |
Back to article view | Back to comp.lang.c
Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 12:01 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 13:15 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 13:27 -0700
Re: Sugestions for runtime polymorphism Richard Heathfield <rjh@cpax.org.uk> - 2016-09-14 21:50 +0100
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 14:20 -0700
Re: Sugestions for runtime polymorphism "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-14 17:32 -0400
Re: Sugestions for runtime polymorphism Keith Thompson <kst-u@mib.org> - 2016-09-14 16:30 -0700
Re: Sugestions for runtime polymorphism "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-14 17:54 -0400
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 17:34 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 17:58 -0700
Re: Sugestions for runtime polymorphism Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-14 19:50 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-15 05:03 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-15 10:43 +0100
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-15 05:29 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-15 19:49 +0100
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-15 11:58 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-15 20:29 +0100
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-15 14:00 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-16 07:27 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-16 16:34 +0100
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-16 09:36 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-20 12:59 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-20 14:08 -0700
Re: Sugestions for runtime polymorphism Ian Collins <ian-news@hotmail.com> - 2016-09-21 15:53 +1200
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-21 07:38 -0700
Re: Sugestions for runtime polymorphism Ian Collins <ian-news@hotmail.com> - 2016-09-23 09:12 +1200
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-21 05:26 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-21 05:35 -0700
Re: Sugestions for runtime polymorphism Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-21 06:01 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 01:44 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-22 13:16 +0100
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-22 08:02 -0700
Re: Sugestions for runtime polymorphism Keith Thompson <kst-u@mib.org> - 2016-09-22 11:44 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-22 09:52 -0700
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-23 09:49 +0200
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-23 07:55 -0700
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-24 16:29 +0200
Re: Sugestions for runtime polymorphism Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-24 15:56 +0100
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-24 17:50 +0200
Re: Sugestions for runtime polymorphism "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-24 13:45 -0400
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-24 11:26 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-28 10:38 -0700
Re: Sugestions for runtime polymorphism Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-24 21:03 +0100
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-25 12:43 +0200
Re: Sugestions for runtime polymorphism "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-25 11:48 -0400
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-25 18:39 +0200
Re: Sugestions for runtime polymorphism "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-25 13:14 -0400
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-25 13:47 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-28 10:39 -0700
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-25 23:25 +0200
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-25 13:10 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-25 12:55 -0700
Re: Sugestions for runtime polymorphism Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-25 20:38 +0100
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-25 23:20 +0200
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-28 07:15 -0700
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-28 21:29 +0200
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-24 10:52 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-24 10:33 -0700
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-25 12:46 +0200
Re: Sugestions for runtime polymorphism Keith Thompson <kst-u@mib.org> - 2016-09-24 13:58 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-28 04:46 -0700
Re: Sugestions for runtime polymorphism Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-24 00:07 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-23 08:52 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-23 09:56 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-23 12:00 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 08:45 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-22 09:36 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-23 12:06 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-23 15:29 -0700
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-29 07:56 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-30 10:54 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-30 11:18 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-30 19:26 +0100
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-30 12:41 -0700
Re: Sugestions for runtime polymorphism Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-30 21:07 +0100
Re: Sugestions for runtime polymorphism Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-30 23:30 -0700
Re: Sugestions for runtime polymorphism Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-10-01 11:35 +0100
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-10-01 14:44 -0700
Re: Sugestions for runtime polymorphism Richard Heathfield <rjh@cpax.org.uk> - 2016-09-14 22:56 +0100
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-15 13:19 +0200
Re: Sugestions for runtime polymorphism James Kuyper <jameskuyper@verizon.net> - 2016-09-15 08:07 -0400
Re: Sugestions for runtime polymorphism David Brown <david.brown@hesbynett.no> - 2016-09-15 14:24 +0200
Re: Sugestions for runtime polymorphism Richard Heathfield <rjh@cpax.org.uk> - 2016-09-15 15:34 +0100
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-15 05:10 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-15 09:12 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-14 23:32 +0100
Re: Sugestions for runtime polymorphism "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-09-14 17:35 -0700
Re: Sugestions for runtime polymorphism Ian Collins <ian-news@hotmail.com> - 2016-09-15 16:24 +1200
Re: Sugestions for runtime polymorphism Keith Thompson <kst-u@mib.org> - 2016-09-15 10:31 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-14 22:53 +0100
Re: Sugestions for runtime polymorphism Keith Thompson <kst-u@mib.org> - 2016-09-14 16:56 -0700
Re: Sugestions for runtime polymorphism supercat@casperkitty.com - 2016-09-14 15:58 -0700
Re: Sugestions for runtime polymorphism Keith Thompson <kst-u@mib.org> - 2016-09-14 18:49 -0700
Re: Sugestions for runtime polymorphism luser droog <luser.droog@gmail.com> - 2016-09-14 14:17 -0700
Re: Sugestions for runtime polymorphism Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 14:25 -0700
Re: Sugestions for runtime polymorphism luser droog <luser.droog@gmail.com> - 2016-09-14 14:40 -0700
Re: Sugestions for runtime polymorphism luser droog <luser.droog@gmail.com> - 2016-09-14 14:57 -0700
Re: Sugestions for runtime polymorphism BartC <bc@freeuk.com> - 2016-09-14 23:10 +0100
Re: Sugestions for runtime polymorphism Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-15 11:23 -0700
Page 1 of 5 [1] 2 3 4 5 Next page →
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-14 12:01 -0700 |
| Subject | Sugestions for runtime polymorphism |
| Message-ID | <b0659440-88ee-4d0f-861e-d5bb1cd0890d@googlegroups.com> |
I need to create an array of "TypeSpecifiers" that are polymorphic. I have the list of all possible types.
Does anyone have suggestions to implement this?
I was thinking is something like:
typedef enum {
ObjectType_TypeSpecifer_Void,
ObjectType_TypeSpecifer_Char,
//...
ObjectType_TypeSpecifer_Struct,
ObjectType_TypeSpecifer_Enum,
} ObjectType;
struct Object
{
ObjectType type;
};
typedef struct
{
struct Object object;
} SimpleTypeSpecifer;
struct StructTypeSpecifer
{
struct Object object;
//more data...
};
struct EnumTypeSpecifer
{
struct Object object;
//more data...
};
typedef union
{
Object* pObject;
SimpleTypeSpecifer* pSimpleTypeSpecifer;
EnumTypeSpecifer* pEnumTypeSpecifer;
StructTypeSpecifer* pStructTypeSpecifer;
} TypeSpecifier;
And then, if I have TypeSpecifier* p then I check the type first
if (p->pObject->type == ObjectType_TypeSpecifer_Void)
...
and use the correct pointer.
[toc] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-14 13:15 -0700 |
| Message-ID | <c394bad8-0750-466f-b694-2d7355cbe8dc@googlegroups.com> |
| In reply to | #93474 |
Sorry, this sample doesn't compile. But it shows that I was trying to use union with all the possible pointers and discover the runtime type using the type enum.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-14 13:27 -0700 |
| Message-ID | <b480679b-8d81-4c8b-bd37-5c846f20f6ea@googlegroups.com> |
| In reply to | #93474 |
This sample compiles and run.
#include <stdio.h>
#include <stdlib.h>
typedef enum {
ObjectType_TypeSpecifer_Void,
ObjectType_TypeSpecifer_Char,
ObjectType_TypeSpecifer_Struct,
ObjectType_TypeSpecifer_Enum,
} ObjectType;
typedef struct
{
ObjectType type;
} Object;
typedef struct
{
Object object;
} SimpleTypeSpecifer;
SimpleTypeSpecifer* SimpleTypeSpecifer_Create(ObjectType type)
{
SimpleTypeSpecifer * p = (SimpleTypeSpecifer *)malloc(sizeof(SimpleTypeSpecifer));
p->object.type = type;
return p;
}
typedef struct
{
Object object;
//more data...
} StructTypeSpecifer;
typedef struct
{
Object object;
//more data...
} EnumTypeSpecifer;
typedef union
{
Object* pObject;
SimpleTypeSpecifer* pSimpleTypeSpecifer;
EnumTypeSpecifer* pEnumTypeSpecifer;
StructTypeSpecifer* pStructTypeSpecifer;
} TypeSpecifier;
int main()
{
//Some array
TypeSpecifier specifiers[1];
//Everthing added as "Object"
specifiers[0].pObject = (Object*)SimpleTypeSpecifer_Create(ObjectType_TypeSpecifer_Void);
for (int i = 0; i < sizeof(specifiers) / sizeof(specifiers[0]); i++)
{
//check
if (specifiers[i].pObject->type == ObjectType_TypeSpecifer_Void)
{
printf("type-specifier = void");
}
}
return 0;
}
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2016-09-14 21:50 +0100 |
| Message-ID | <nrcd6m$7te$1@dont-email.me> |
| In reply to | #93485 |
On 14/09/16 21:27, Thiago Adams wrote:
> This sample compiles and run.
>
> #include <stdio.h>
> #include <stdlib.h>
>
>
> typedef enum {
>
> ObjectType_TypeSpecifer_Void,
Did you mean TypeSpecifier? In my experience, mis-spellings are best
corrected sooner rather than later, before they pollute the whole code base.
> ObjectType_TypeSpecifer_Char,
> ObjectType_TypeSpecifer_Struct,
> ObjectType_TypeSpecifer_Enum,
>
> } ObjectType;
>
> typedef struct
> {
> ObjectType type;
> } Object;
>
> typedef struct
> {
> Object object;
> } SimpleTypeSpecifer;
>
> SimpleTypeSpecifer* SimpleTypeSpecifer_Create(ObjectType type)
> {
> SimpleTypeSpecifer * p = (SimpleTypeSpecifer *)malloc(sizeof(SimpleTypeSpecifer));
Why not just:
SimpleTypeSpecifer * p = malloc(sizeof *p);
> p->object.type = type;
You forgot something important. This should be:
if(p != NULL)
{
p->object.type = type;
}
> return p;
> }
>
> typedef struct
> {
> Object object;
> //more data...
> } StructTypeSpecifer;
>
> typedef struct
> {
> Object object;
> //more data...
> } EnumTypeSpecifer;
>
> typedef union
> {
> Object* pObject;
> SimpleTypeSpecifer* pSimpleTypeSpecifer;
> EnumTypeSpecifer* pEnumTypeSpecifer;
> StructTypeSpecifer* pStructTypeSpecifer;
> } TypeSpecifier;
>
>
>
> int main()
> {
> //Some array
> TypeSpecifier specifiers[1];
>
> //Everthing added as "Object"
> specifiers[0].pObject = (Object*)SimpleTypeSpecifer_Create(ObjectType_TypeSpecifer_Void);
>
> for (int i = 0; i < sizeof(specifiers) / sizeof(specifiers[0]); i++)
> {
> //check
> if (specifiers[i].pObject->type == ObjectType_TypeSpecifer_Void)
> {
> printf("type-specifier = void");
> }
> }
>
> return 0;
> }
This seems like a lot of trouble to take over types. Why not just trust
that the user-programmer knows what type he put into the array, and that
he'll know to take that type out again?
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-14 14:20 -0700 |
| Message-ID | <672e5191-f11d-4ac3-ad56-910569c12f48@googlegroups.com> |
| In reply to | #93487 |
On Wednesday, September 14, 2016 at 5:50:50 PM UTC-3, Richard Heathfield > Did you mean TypeSpecifier? In my experience, mis-spellings are best
> corrected sooner rather than later, before they pollute the whole code base.
Yes!
> Why not just:
>
> SimpleTypeSpecifer * p = malloc(sizeof *p);
I use visual C++, and I compile the same code in C and C++. For the Microsoft compilers, the C++ version is usually better. (Produces more error messages and faster exe)
So the "C/C++ version" requires more casts.
But this:
SimpleTypeSpecifer * p = (SimpleTypeSpecifer *) malloc(sizeof *p);
works. I liked it.
> You forgot something important. This should be:
>
> if(p != NULL)
> {
> p->object.type = type;
> }
>
> > return p;
> > }
Yes. This would be my next question.
How do you handle memory failure in your programs.
This is a parser program. Probably the best thing to do is exit on memory failure. But I may regret this decision in the future.
> This seems like a lot of trouble to take over types. Why not just trust
> that the user-programmer knows what type he put into the array, and that
> he'll know to take that type out again?
This is a runtime problem. Nobody knows what the types are there...we need some runtime "id" and them cast.
This will be AST for the C language. I need visit the nodes after.
But the question is general.
If you need 0..N shapes and a shape can be rectangle , circle or ellipse how would you do?
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2016-09-14 17:32 -0400 |
| Message-ID | <6ba3d832-8a50-a731-6c24-f02d87a42bdc@verizon.net> |
| In reply to | #93491 |
On 09/14/2016 05:20 PM, Thiago Adams wrote: ... > How do you handle memory failure in your programs. > > This is a parser program. Probably the best thing to do is exit on memory failure. But I may regret this decision in the future. IMO, having low level routines decide that an entire program should exit is not a good idea. When writing such routines, you're focusing in on one time part of the problem. The decision to exit should be made at a higher level, with a broader scope of information available. Therefore, have the routine return an error code identifying the problem to the calling routine, and let the calling routine decide what to do about it (which might be to pass the problem on to it's own caller). In many cases, simply returning a null pointer value (which is what malloc() gives you when it fails) would be enough. Just make sure that the null value never gets used!
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-09-14 16:30 -0700 |
| Message-ID | <lnmvja3vqz.fsf@kst-u.example.com> |
| In reply to | #93494 |
"James R. Kuyper" <jameskuyper@verizon.net> writes:
[...]
> In many cases, simply returning a null pointer value (which is what
> malloc() gives you when it fails) would be enough. Just make sure that
> the null value never gets used!
s/used/dereferenced/
(which I'm sure is what you meant).
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2016-09-14 17:54 -0400 |
| Message-ID | <9452d30b-303b-477f-2842-a0db8eaae036@verizon.net> |
| In reply to | #93498 |
On 09/14/2016 07:30 PM, Keith Thompson wrote: > "James R. Kuyper" <jameskuyper@verizon.net> writes: > [...] >> In many cases, simply returning a null pointer value (which is what >> malloc() gives you when it fails) would be enough. Just make sure that >> the null value never gets used! > > s/used/dereferenced/ > > (which I'm sure is what you meant). Yes, my wording was sloppy.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-14 17:34 -0700 |
| Message-ID | <1e5434a5-e6d1-45f2-a4ac-ce566713b375@googlegroups.com> |
| In reply to | #93494 |
On Wednesday, September 14, 2016 at 6:32:47 PM UTC-3, James R. Kuyper wrote: > On 09/14/2016 05:20 PM, Thiago Adams wrote: > ... > > How do you handle memory failure in your programs. > > > > This is a parser program. Probably the best thing to do is exit on memory failure. But I may regret this decision in the future. > > IMO, having low level routines decide that an entire program should exit > is not a good idea. When writing such routines, you're focusing in on > one time part of the problem. The decision to exit should be made at a > higher level, with a broader scope of information available. Therefore, > have the routine return an error code identifying the problem to the > calling routine, and let the calling routine decide what to do about it > (which might be to pass the problem on to it's own caller). > > In many cases, simply returning a null pointer value (which is what > malloc() gives you when it fails) would be enough. Just make sure that > the null value never gets used! I agree. But I have see programs like git, that make the decision to log and close and this simplifies a lot of error handling.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-14 17:58 -0700 |
| Message-ID | <376d191c-1ad2-47f6-b8ed-0811ecc7babc@googlegroups.com> |
| In reply to | #93512 |
More details about the real problem. I will replace the representation I have for the C parser. Today my data is a kind of "json" in memory. I want to change for something more statically typed. I want something ease to use. So, I have declarations, type-specifiers, type-qualifiers etc.. type-specifiers can be void, int, long, unsigned, char ... or struct, union enum. These types have different data inside. Inside a "declaration" for instance, I need a list of "specifiers". A list of qualifies, declarators. So the specifiers can have different types. The Object that I had create, I was thinking in to use as a "base" class for everything. For qualifiers as well. This was confusing here because it was not related directed with the specifiers. Later, I need to visit these nodes. I need to generate a json file. I need go up and down on the tree. So I am starting to think how I will declare this data struct (AST) in C. I don't need something very memory efficient. I need something easy to use to create an static code analysis. I was trying the union as something new to identify a set of all possible types.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-09-14 19:50 -0700 |
| Message-ID | <06116b16-e642-4aa3-a1cd-953fe249be9d@googlegroups.com> |
| In reply to | #93514 |
On Thursday, September 15, 2016 at 1:58:57 AM UTC+1, Thiago Adams wrote:
> More details about the real problem.
>
> I will replace the representation I have for the C parser. Today my
> data is a kind of "json" in memory. I want to change for something
> more statically typed. I want something ease to use.
>
> So, I have declarations, type-specifiers, type-qualifiers etc..
>
> type-specifiers can be void, int, long, unsigned, char ... or struct,
> union enum.
> These types have different data inside.
>
> Inside a "declaration" for instance, I need a list of "specifiers". A
> list of qualifies, declarators.
>
> So the specifiers can have different types. The Object that I had
> create, I was thinking in to use as a "base" class for everything.
> For qualifiers as well. This was confusing here because it was not
> related directed with the specifiers.
>
> Later, I need to visit these nodes. I need to generate a json file.
> I need go up and down on the tree.
>
> So I am starting to think how I will declare this data struct (AST) in C.
> I don't need something very memory efficient. I need something easy
> to use to create an static code analysis.
>
> I was trying the union as something new to identify a set of all
> possible types.
>
Use the COM method.
An "interface" is a table of function pointers. You either have a restricted
number in the program, in which case they are represented by an enum
type, or you have an unrestricted number, in which case give them
names which are strings.
Pass everything about as COM *s. A COM * basically supports only one
method
void *com_query_interface(COM *com, int or char * interface_id)
Then we have an interface like this
typedef struct
{
bool (*hasField)(COM *com, char *fieldname);
int (*getIntegerField)(COM *com, char *fieldname);
char * (*getStringField)(COM *com, char *fieldname);
char * (*getJSON)(COM *com);
COM *getobjectField(COM *com, char *filedname);
} INTERFACE_JSON;
So your first object can expose the JSON interface. Now as it happens,
in the code base you have this
{
"walk": 100,
"quack" : "say quack quack",
"type" : "Mallard",
}
So currently the JSON code goes along the lines of
if( json_hasfield(jsonobj, "quack"))
printf("%s\n", json_getfield(jsononj, "quack"))
so that is quickly replaced
COM *comobj;
INTERFACE_JSON *json;;
if(json = com_query_interface(comobj, "JSON"))
{
if( json->hasField(comobj, "quack") )
{
printf("%s\n", json->GetField(com, "quack"));
}
}
So it all goes over with just one additional check. Now we want to
make life a bit less generic.
so
typedef struct
{
void (*quack)(COM *com);
} INTERFACE_DUCK;
and the code becomes
COM *comobj;
INTERFACE_DUCK duck;
if(duck = com_query_interface(comobj, "DUCK") )
duck->quack(comobj);
Now at this point, the duck object still supports INTERFACE_JSON.
So we can toggle between the two methods.
However eventually everything is converted over to use INTERFACE_DUCK.
So remove the JSON interface, and have it return null. If you've
missed a bit, code now compiled but breaks - the duck won't quack
but it won't crash out either.
Finally you can remove the COM machinery and just pass a DUCK *
if you want to get rid of all generic programming.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-15 05:03 -0700 |
| Message-ID | <15607834-71c9-4673-a2d0-86fd5f40aad1@googlegroups.com> |
| In reply to | #93520 |
On Wednesday, September 14, 2016 at 11:50:19 PM UTC-3, Malcolm McLean wrote:
> On Thursday, September 15, 2016 at 1:58:57 AM UTC+1, Thiago Adams wrote:
> > More details about the real problem.
> >
> > I will replace the representation I have for the C parser. Today my
> > data is a kind of "json" in memory. I want to change for something
> > more statically typed. I want something ease to use.
> >
> > So, I have declarations, type-specifiers, type-qualifiers etc..
> >
> > type-specifiers can be void, int, long, unsigned, char ... or struct,
> > union enum.
> > These types have different data inside.
> >
> > Inside a "declaration" for instance, I need a list of "specifiers". A
> > list of qualifies, declarators.
> >
> > So the specifiers can have different types. The Object that I had
> > create, I was thinking in to use as a "base" class for everything.
> > For qualifiers as well. This was confusing here because it was not
> > related directed with the specifiers.
> >
> > Later, I need to visit these nodes. I need to generate a json file.
> > I need go up and down on the tree.
> >
> > So I am starting to think how I will declare this data struct (AST) in C.
> > I don't need something very memory efficient. I need something easy
> > to use to create an static code analysis.
> >
> > I was trying the union as something new to identify a set of all
> > possible types.
> >
> Use the COM method.
>
> An "interface" is a table of function pointers. You either have a restricted
> number in the program, in which case they are represented by an enum
> type, or you have an unrestricted number, in which case give them
> names which are strings.
>
> Pass everything about as COM *s. A COM * basically supports only one
> method
>
> void *com_query_interface(COM *com, int or char * interface_id)
>
> Then we have an interface like this
>
> typedef struct
> {
> bool (*hasField)(COM *com, char *fieldname);
> int (*getIntegerField)(COM *com, char *fieldname);
> char * (*getStringField)(COM *com, char *fieldname);
> char * (*getJSON)(COM *com);
> COM *getobjectField(COM *com, char *filedname);
> } INTERFACE_JSON;
>
> So your first object can expose the JSON interface. Now as it happens,
> in the code base you have this
>
> {
> "walk": 100,
> "quack" : "say quack quack",
> "type" : "Mallard",
> }
>
> So currently the JSON code goes along the lines of
>
> if( json_hasfield(jsonobj, "quack"))
> printf("%s\n", json_getfield(jsononj, "quack"))
>
> so that is quickly replaced
>
> COM *comobj;
> INTERFACE_JSON *json;;
>
> if(json = com_query_interface(comobj, "JSON"))
> {
> if( json->hasField(comobj, "quack") )
> {
> printf("%s\n", json->GetField(com, "quack"));
> }
> }
>
> So it all goes over with just one additional check. Now we want to
> make life a bit less generic.
>
> so
>
> typedef struct
> {
> void (*quack)(COM *com);
> } INTERFACE_DUCK;
>
> and the code becomes
>
> COM *comobj;
> INTERFACE_DUCK duck;
>
> if(duck = com_query_interface(comobj, "DUCK") )
> duck->quack(comobj);
>
> Now at this point, the duck object still supports INTERFACE_JSON.
> So we can toggle between the two methods.
> However eventually everything is converted over to use INTERFACE_DUCK.
> So remove the JSON interface, and have it return null. If you've
> missed a bit, code now compiled but breaks - the duck won't quack
> but it won't crash out either.
>
> Finally you can remove the COM machinery and just pass a DUCK *
> if you want to get rid of all generic programming.
I am familiar with COM. I like COM method when we don't known the final types. For instance, to implement a IDE syntax color plug-in.
In this case, I known all possible types. I think COM style will complicated.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-09-15 10:43 +0100 |
| Message-ID | <nrdqgg$mu4$1@dont-email.me> |
| In reply to | #93514 |
On 15/09/2016 01:58, Thiago Adams wrote: > I will replace the representation I have for the C parser. Today my data is a kind of "json" in memory. I want to change for something more statically typed. I want something ease to use. > > So, I have declarations, type-specifiers, type-qualifiers etc.. > > type-specifiers can be void, int, long, unsigned, char ... or struct, union enum. > These types have different data inside. > > Inside a "declaration" for instance, I need a list of "specifiers". A list of qualifies, declarators. > > So the specifiers can have different types. The Object that I had create, I was thinking in to use as a "base" class for everything. For qualifiers as well. This was confusing here because it was not related directed with the specifiers. > > Later, I need to visit these nodes. I need to generate a json file. I need go up and down on the tree. > > So I am starting to think how I will declare this data struct (AST) in C. > I don't need something very memory efficient. I need something easy to use to create an static code analysis. > > I was trying the union as something new to identify a set of all possible types. So, this is like implementing part of a compiler? And to represent, what, the statement structure of a program, the expression structure, and type-structure? The latter, for something like 'int (**A)[]'? Well, you seem to be over-complicating matters a little! (Or perhaps my own approaches might be over-simplified.) To represent something like the above, I make use of only three kinds of struct: - To represent an entry in a symbol table (the ST) - To represent a node of a statement or expression (the AST) - To represent an arbitrary type The first two are probably stretched a little to cover multiple different kinds of symbols (maybe 20 kinds; this is not for C so rather more than C needs); and obviously multiple kinds of statement and expression terms. The Type struct is usually straightforward until it comes to types involving arbitrary lists of elements: structs, enums and function pointers. Here it uses a combination of Type struct and Symbol struct. But because this is not for C, differences in language mean a C version would need to work a little differently (for example I treat function pointers separately from actual functions; the latter are not types). BTW another group that might have ideas (although moderated so posts take a while to appear) is comp.compilers, where they are very much into parsers and all that stuff. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-15 05:29 -0700 |
| Message-ID | <52493fe0-da8d-46ca-b38d-d811e3fad940@googlegroups.com> |
| In reply to | #93527 |
On Thursday, September 15, 2016 at 6:43:59 AM UTC-3, Bart wrote:
> On 15/09/2016 01:58, Thiago Adams wrote:
>
> > I will replace the representation I have for the C parser. Today my data is a kind of "json" in memory. I want to change for something more statically typed. I want something ease to use.
> >
> > So, I have declarations, type-specifiers, type-qualifiers etc..
> >
> > type-specifiers can be void, int, long, unsigned, char ... or struct, union enum.
> > These types have different data inside.
> >
> > Inside a "declaration" for instance, I need a list of "specifiers". A list of qualifies, declarators.
> >
> > So the specifiers can have different types. The Object that I had create, I was thinking in to use as a "base" class for everything. For qualifiers as well. This was confusing here because it was not related directed with the specifiers.
> >
> > Later, I need to visit these nodes. I need to generate a json file. I need go up and down on the tree.
> >
> > So I am starting to think how I will declare this data struct (AST) in C.
> > I don't need something very memory efficient. I need something easy to use to create an static code analysis.
> >
> > I was trying the union as something new to identify a set of all possible types.
>
> So, this is like implementing part of a compiler? And to represent,
> what, the statement structure of a program, the expression structure,
> and type-structure? The latter, for something like 'int (**A)[]'?
>
> Well, you seem to be over-complicating matters a little! (Or perhaps my
> own approaches might be over-simplified.)
>
> To represent something like the above, I make use of only three kinds of
> struct:
>
> - To represent an entry in a symbol table (the ST)
>
> - To represent a node of a statement or expression (the AST)
>
> - To represent an arbitrary type
>
> The first two are probably stretched a little to cover multiple
> different kinds of symbols (maybe 20 kinds; this is not for C so rather
> more than C needs); and obviously multiple kinds of statement and
> expression terms.
>
> The Type struct is usually straightforward until it comes to types
> involving arbitrary lists of elements: structs, enums and function
> pointers. Here it uses a combination of Type struct and Symbol struct.
>
> But because this is not for C, differences in language mean a C version
> would need to work a little differently (for example I treat function
> pointers separately from actual functions; the latter are not types).
>
> BTW another group that might have ideas (although moderated so posts
> take a while to appear) is comp.compilers, where they are very much into
> parsers and all that stuff.
>
> --
> Bartc
So, this is like implementing part of a compiler? And to represent,
what, the statement structure of a program, the expression structure,
and type-structure? The latter, for something like 'int (**A)[]'?
Yes.
For instance:
Today this line:
const unsigned long long i;
outputs:
{
"_type": "declaration",
"declaration-specifiers":
{
"_type": "declaration-specifiers",
"type-qualifier": [ "const" ],
"type-specifier": [ "unsigned", "long", "long"]
},
"declarator-list":
[
{
"name": "i",
"_type": "declarator",
"pointers":[]
}
]
}
and this line:
struct X { int i; };
{
"_type": "declaration",
"declaration-specifiers":
{
"_type": "declaration-specifiers",
"type-specifier":
{
"name": "X",
"_type": "struct-specifier",
"struct-declaration-list":
[
{
"_type": "declaration",
"declaration-specifiers":
{
"_type": "declaration-specifiers",
"type-specifier": ["int"]
},
"declarator-list":
[
{
"name": "i",
"_type": "declarator",
"pointers":[]
}
]
}
]
}
}
}
I was focusing the question on the "type-specifier" part, that
can change a lot.
Today a have this json in memory. I want to change to something more formal and static with proper types.
My question was polymorphism in C in general, but I
understand that the best answer must known the real details.
The AST I am building follows (moreless) the C grammar.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-09-15 19:49 +0100 |
| Message-ID | <nreqg5$7b7$1@dont-email.me> |
| In reply to | #93537 |
On 15/09/2016 13:29, Thiago Adams wrote:
> On Thursday, September 15, 2016 at 6:43:59 AM UTC-3, Bart wrote:
>> So, this is like implementing part of a compiler? And to represent,
>> what, the statement structure of a program, the expression structure,
>> and type-structure? The latter, for something like 'int (**A)[]'?
> Yes.
> For instance:
> Today this line:
>
> const unsigned long long i;
>
> outputs:
>
> {
> "_type": "declaration",
> "declaration-specifiers":
> {
> "_type": "declaration-specifiers",
> "type-qualifier": [ "const" ],
> "type-specifier": [ "unsigned", "long", "long"]
> },
> "declarator-list":
> [
> {
> "name": "i",
> "_type": "declarator",
> "pointers":[]
> }
> ]
> }
This is Json? I don't understand what transformation has been done here,
other than formalise the structure of the input into machine-readable form.
However, this hasn't converted the (unsigned, long, long) specifiers
into something concrete such as 'uint64_t'.
In other words, it still needs another pass to make sense of the code,
and generate something useful for analysis.
Is the above supposed to correspond to C's formal grammar? That's not
particularly easy to understand, and mainly exists to tell you what is
legal source code and what isn't. This is simpler output for your example:
{declaration:
name: "i"
type: T1
static: ...
...
}
T1:{anonymous type:
basetype: unsigned-int
width: 64
size: 8
const: yes
}
In this form, the type "T1" can be shared by multiple names:
const unsigned long long i,j,k;
And makes it easier to see if two types are the same.
> My question was polymorphism in C in general, but I
> understand that the best answer must known the real details.
Actually I can't see what polymorphism has to do with any of the above.
--
Bartc
> The AST I am building follows (moreless) the C grammar.
>
>
>
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-15 11:58 -0700 |
| Message-ID | <62822054-7d11-49da-8a61-134ce2639126@googlegroups.com> |
| In reply to | #93559 |
On Thursday, September 15, 2016 at 3:49:55 PM UTC-3, Bart wrote:
> On 15/09/2016 13:29, Thiago Adams wrote:
> > On Thursday, September 15, 2016 at 6:43:59 AM UTC-3, Bart wrote:
>
> >> So, this is like implementing part of a compiler? And to represent,
> >> what, the statement structure of a program, the expression structure,
> >> and type-structure? The latter, for something like 'int (**A)[]'?
>
> > Yes.
> > For instance:
> > Today this line:
> >
> > const unsigned long long i;
> >
> > outputs:
> >
> > {
> > "_type": "declaration",
> > "declaration-specifiers":
> > {
> > "_type": "declaration-specifiers",
> > "type-qualifier": [ "const" ],
> > "type-specifier": [ "unsigned", "long", "long"]
> > },
> > "declarator-list":
> > [
> > {
> > "name": "i",
> > "_type": "declarator",
> > "pointers":[]
> > }
> > ]
> > }
>
> This is Json? I don't understand what transformation has been done here,
> other than formalise the structure of the input into machine-readable form.
>
> However, this hasn't converted the (unsigned, long, long) specifiers
> into something concrete such as 'uint64_t'.
>
> In other words, it still needs another pass to make sense of the code,
> and generate something useful for analysis.
>
> Is the above supposed to correspond to C's formal grammar? That's not
> particularly easy to understand, and mainly exists to tell you what is
> legal source code and what isn't. This is simpler output for your example:
To get an idea about the AST this is about the clang AST
http://clang.llvm.org/docs/IntroductionToTheClangAST.html
The C grammar doesn't correspond to data structures directly.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-09-15 20:29 +0100 |
| Message-ID | <nresr3$g2s$1@dont-email.me> |
| In reply to | #93561 |
On 15/09/2016 19:58, Thiago Adams wrote:
> On Thursday, September 15, 2016 at 3:49:55 PM UTC-3, Bart wrote:
>> On 15/09/2016 13:29, Thiago Adams wrote:
>>> const unsigned long long i;
>>>
>>> outputs:
>>>
>>> {
>>> "_type": "declaration",
>>> "declaration-specifiers":
>>> {
>>> "_type": "declaration-specifiers",
>>> "type-qualifier": [ "const" ],
>>> "type-specifier": [ "unsigned", "long", "long"]
>>> },
>>> "declarator-list":
>>> [
>>> {
>>> "name": "i",
>>> "_type": "declarator",
>>> "pointers":[]
>>> }
>>> ]
>>> }
>>
>> Is the above supposed to correspond to C's formal grammar? That's not
>> particularly easy to understand, and mainly exists to tell you what is
>> legal source code and what isn't. This is simpler output for your example:
>
> To get an idea about the AST this is about the clang AST
> http://clang.llvm.org/docs/IntroductionToTheClangAST.html
Oh, llvm. That's a very large, complicated system and I try to have as
little to do with as possible.
But even so, the AST example in your llvm link still looks much simpler
than your Json stuff above.
What would do llvm AST show when applied to 'const unsigned long long'?
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-15 14:00 -0700 |
| Message-ID | <666af99b-9b6b-4f1a-a1a3-498ab48d6f44@googlegroups.com> |
| In reply to | #93567 |
On Thursday, September 15, 2016 at 4:29:53 PM UTC-3, Bart wrote:
> On 15/09/2016 19:58, Thiago Adams wrote:
> > On Thursday, September 15, 2016 at 3:49:55 PM UTC-3, Bart wrote:
> >> On 15/09/2016 13:29, Thiago Adams wrote:
>
> >>> const unsigned long long i;
> >>>
> >>> outputs:
> >>>
> >>> {
> >>> "_type": "declaration",
> >>> "declaration-specifiers":
> >>> {
> >>> "_type": "declaration-specifiers",
> >>> "type-qualifier": [ "const" ],
> >>> "type-specifier": [ "unsigned", "long", "long"]
> >>> },
> >>> "declarator-list":
> >>> [
> >>> {
> >>> "name": "i",
> >>> "_type": "declarator",
> >>> "pointers":[]
> >>> }
> >>> ]
> >>> }
> >>
>
> >> Is the above supposed to correspond to C's formal grammar? That's not
> >> particularly easy to understand, and mainly exists to tell you what is
> >> legal source code and what isn't. This is simpler output for your example:
> >
> > To get an idea about the AST this is about the clang AST
> > http://clang.llvm.org/docs/IntroductionToTheClangAST.html
>
> Oh, llvm. That's a very large, complicated system and I try to have as
> little to do with as possible.
>
> But even so, the AST example in your llvm link still looks much simpler
> than your Json stuff above.
>
> What would do llvm AST show when applied to 'const unsigned long long'?
>
clang -cc1 -ast-dump f1.c
It shows:
...
-VarDecl 0x44fe598 <f1.c:1:1, col:26> col:26 i 'const unsigned long long'
If I change for:
long unsigned const long i;
It shows the same:
-VarDecl 0x7dbf78 <f1.c:2:1, col:27> col:27 i 'const unsigned long long'
So it rebuilds the type in a string form.
This is the first time I run this command.
My conclusion? clang doesn't follow the grammar in their ast.
const int a, b;
-VarDecl 0x47ff2d8 <f1.c:1:1, col:11> col:11 a 'const int'
-VarDecl 0x47ff348 <col:1, col:14> col:14 b 'const int'
My output for const int a, b;
{
"_type": "declaration",
"declaration-specifiers":
{
"_type": "declaration-specifiers",
"type-qualifier": ["const"],
"type-specifier": ["int"]
},
"declarator-list":
[
{
"name": "a",
"_type": "declarator",
"pointers": []
},
{
"name": "b",
"_type": "declarator",
"pointers":[]
}
]
}
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2016-09-16 07:27 -0700 |
| Message-ID | <5be0e169-cd80-4785-b2c8-934e71cf1164@googlegroups.com> |
| In reply to | #93577 |
Probably I will do this: (maybe this is my last version before implement)
Any suggestion is welcome.
typedef enum {
CatType,
BananaType,
AirplaneType
} Type;
typedef struct
{
Type type;
int color;
} Banana;
typedef struct
{
Type type;
int color;
} Cat;
typedef struct TAirplane
{
Type type;
int color;
} Airplane;
typedef union {
Cat* pCat;
Banana* pBanana;
} Node2;
typedef union {
Airplane* pAirplane;
Banana* pBanana;
} Node1;
#define IS_TYPE(X, T) (((struct {Type type;}*) (&X))->type == T)
int main()
{
Node1 node;
node.pAirplane = malloc(sizeof *node.pAirplane);
node.pAirplane->type = AirplaneType;
if (IS_TYPE(node, AirplaneType))
{
//yes I am an airplane
}
return 0;
}
Why I liked this solution?
There are no dangerous casts, and IDE with auto complete make life easier to find-out options and use the object.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-09-16 16:34 +0100 |
| Message-ID | <nrh3f1$m25$1@dont-email.me> |
| In reply to | #93621 |
On 16/09/2016 15:27, Thiago Adams wrote:
>
> Probably I will do this: (maybe this is my last version before implement)
>
> Any suggestion is welcome.
>
>
> typedef enum {
> CatType,
> BananaType,
> AirplaneType
> } Type;
>
> typedef struct
> {
> Type type;
> int color;
> } Banana;
>
> typedef struct
> {
> Type type;
> int color;
> } Cat;
>
> typedef struct TAirplane
> {
> Type type;
> int color;
> } Airplane;
>
>
> typedef union {
> Cat* pCat;
> Banana* pBanana;
> } Node2;
>
> typedef union {
> Airplane* pAirplane;
> Banana* pBanana;
> } Node1;
>
> #define IS_TYPE(X, T) (((struct {Type type;}*) (&X))->type == T)
>
> int main()
> {
> Node1 node;
> node.pAirplane = malloc(sizeof *node.pAirplane);
> node.pAirplane->type = AirplaneType;
>
> if (IS_TYPE(node, AirplaneType))
> {
> //yes I am an airplane
> }
>
> return 0;
> }
It looks good, especially with the short, snappy identifiers.
However, you might consider taking the Type outside of the Airplane,
Banana and Cat structs. After all each struct knows what it is!
--
Bartc
[toc] | [prev] | [next] | [standalone]
Page 1 of 5 [1] 2 3 4 5 Next page →
Back to top | Article view | comp.lang.c
csiph-web