473,804 Members | 3,958 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Some issue with pointers


Hello,

I need some help to understand what I'm doing :)

I'm writing code for an embedded system and I need to create a navigable
menu system. I'm going to use these structures:

typedef struct {
char *name[2];
int type;
int num_param;
void *ptr;
} menuitem_t;

typedef struct {
char *name[2];
int num_items;
menuitem_t *items;
} menu_t;
The latter defines each menu or submenu with a name, a number of items
and a pointer to the items structure.

The former defines each menu item with a name, a type (see below) the
number of parameters - if any - and finally a generic pointer (see below
again).

In this way I can generate menus of any complexity and very flexible.
The void pointer should point to another menu_t struct if the item leads
to a submenu, to an array if it leads to a parameter list. But it could
also leads to a function if the selection of this item needs an action
to be executed.

Actually I have two questions:

1) I can't cast correctly the void *ptr. Let's say I want to access to:

char *par[] = {"First", "Second"};

ot invoke:

void myfunc();

Please, may you help me to understand how to cast and then to use that
pointer in these cases?

2) It would be nice if I can know the path the user is following. For
example:

mainmenu -seconditem -firstitem

where each of these entities are menu_t structs.
How would you implement such a dynamic path?

Thank you and I apologize for my poor English
Marco / iw2nzm
Jun 30 '08 #1
19 1304
Marco Trapanese <ma************ ******@gmail.co mwrites:
I'm writing code for an embedded system and I need to create a
navigable menu system. I'm going to use these structures:

typedef struct {
char *name[2];
int type;
int num_param;
void *ptr;
} menuitem_t;

typedef struct {
char *name[2];
int num_items;
menuitem_t *items;
} menu_t;
The latter defines each menu or submenu with a name, a number of items
and a pointer to the items structure.

The former defines each menu item with a name, a type (see below) the
number of parameters - if any - and finally a generic pointer (see
below again).
I can't see why you'd have two. I'd merge them like this:

typedef struct menu {
char *name[2];
int type;
int num_param;
union {
void *vp;
struct menu *items;
} ptr;
} menu_t;

It must be simpler to have only one type (in the C sense) for menu
items, surely?
In this way I can generate menus of any complexity and very
flexible. The void pointer should point to another menu_t struct if
the item leads to a submenu, to an array if it leads to a parameter
list. But it could also leads to a function if the selection of this
item needs an action to be executed.
Function pointers are "special" in that there is no guarantee in C
that you can convert a void * to function pointer (nor vice versa).
Your implementation may offer this as an extension, but if you use a
union, you can add a function pointer type and not have any
portability worries.
Actually I have two questions:

1) I can't cast correctly the void *ptr. Let's say I want to access to:

char *par[] = {"First", "Second"};
Let's say that ptr got set like this: 'ptr = par;'. ptr is then a
char ** in disguise so simply writing:

char **strings = ptr;

would let you access strings[0] and strings[1].
ot invoke:

void myfunc();

Please, may you help me to understand how to cast and then to use that
pointer in these cases?
It is easiest not to use a cast. Just assign ptr to a variable of the
right type and off you go.

However, since this requires an extension to standard C, you might
want to consider using a union containing an element for each pointer
type you need. This means you don't have to reply on converting a
void * to a function pointer and it keeps the code very clean (at the
expense of a messy union).
2) It would be nice if I can know the path the user is following. For
example:

mainmenu -seconditem -firstitem

where each of these entities are menu_t structs.
How would you implement such a dynamic path?
I'd use a stack, probably implemented as a linked list.

--
Ben.
Jun 30 '08 #2
Ben Bacarisse ha scritto:
I can't see why you'd have two. I'd merge them like this:

typedef struct menu {
char *name[2];
int type;
int num_param;
union {
void *vp;
struct menu *items;
} ptr;
} menu_t;

It must be simpler to have only one type (in the C sense) for menu
items, surely?
You're right, it's my fault. I'm not so experienced (yet) in this kind
of thing!

Function pointers are "special" in that there is no guarantee in C
that you can convert a void * to function pointer (nor vice versa).
What a pity! :)

Your implementation may offer this as an extension, but if you use a
union, you can add a function pointer type and not have any
portability worries.
So, are you suggesting to add in the union a pointer for each type I
need, aren't you? Or at least, the function pointer because is treated
differently.

>char *par[] = {"First", "Second"};

Let's say that ptr got set like this: 'ptr = par;'. ptr is then a
char ** in disguise so simply writing:

char **strings = ptr;

would let you access strings[0] and strings[1].
Ok, I was trying to access directly from ptr with a cast. But it's more
readable you solution.

It is easiest not to use a cast. Just assign ptr to a variable of the
right type and off you go.

However, since this requires an extension to standard C, you might
want to consider using a union containing an element for each pointer
type you need. This means you don't have to reply on converting a
void * to a function pointer and it keeps the code very clean (at the
expense of a messy union).

Ok, this answer my first question above. I read the 'type' value and use
the correct union entry. The others will be ignored.

I'd use a stack, probably implemented as a linked list.
I got it.

Thank you a lot for the time you spent!

Marco / iw2nzm
Jul 1 '08 #3
Ben Bacarisse ha scritto:
I can't see why you'd have two. I'd merge them like this:

typedef struct menu {
char *name[2];
int type;
int num_param;
union {
void *vp;
struct menu *items;
} ptr;
} menu_t;

Please, consider this short code:
char mypar[3];
void myfunc();

typedef struct menu {
char *name[2];
int type;
int num_param;
union {
void *vp;
void (*fp)();
struct menu *items;
} ptr;
} menu_t;
Ok, now I want to initialize this struct:

const menu_t mn_mnu = {
{"Main Menu", "Menu"},
MIT_FUNCTION,
0,
{mypar}
};
It successfully compiles. Please note that the function pointer
declaration in Dynamic C is slightly different from standard-C. The
syntax is the same: returntype (*name)(); also for functions with
parameters.

Now I want to initialize the second (and eventually the third) element
of the union. How should I do?

{, myfunc}
{0, myfunc}
{NULL, myfunc}

None of these works. The compiler screams loud a lot of errors.
I'm googled on this but I didn't find an example.

Bye
Marco / iw2nzm
Jul 1 '08 #4

I'll keep my replies to this thread. In the other reply you asked a
question. Imagine that I relied to it "yes".

Marco Trapanese <ma************ ******@gmail.co mwrites:
Ben Bacarisse ha scritto:
>I can't see why you'd have two. I'd merge them like this:

typedef struct menu {
char *name[2];
int type;
int num_param;
union {
void *vp;
struct menu *items;
} ptr;
} menu_t;


Please, consider this short code:

char mypar[3];
void myfunc();

typedef struct menu {
char *name[2];
int type;
int num_param;
union {
void *vp;
void (*fp)();
struct menu *items;
} ptr;
} menu_t;
Ok, now I want to initialize this struct:

const menu_t mn_mnu = {
{"Main Menu", "Menu"},
MIT_FUNCTION,
0,
{mypar}
};
It successfully compiles. Please note that the function pointer
declaration in Dynamic C is slightly different from standard-C. The
syntax is the same: returntype (*name)(); also for functions with
parameters.

Now I want to initialize the second (and eventually the third) element
of the union. How should I do?

{, myfunc}
{0, myfunc}
{NULL, myfunc}
You need to either

(1) Use C99 designated initialiser syntax:

{ .fp = myfunc }

(2) Let the compiler complain about the type-mismatch (if it works):

{ myfunc }

(3) Convert to void * (again, if that is permitted):

{ (void *)myfunc }

You don't loose anything this way. In your method, you were still
going to have to initialise a void * with a function pointer which is
what the above does (with C99 you can only initialise the first
element of a union).

Of course, you can do it at runtime (mn_mnu.ptr.fp = myfunc;) but then
you can have the menu as const.

--
Ben.
Jul 1 '08 #5
Ben Bacarisse ha scritto:
(1) Use C99 designated initialiser syntax:

{ .fp = myfunc }

This one doesn't work. I bet Dynamic C is not C99 compliant.

(2) Let the compiler complain about the type-mismatch (if it works):

{ myfunc }

(3) Convert to void * (again, if that is permitted):

{ (void *)myfunc }
These works, or at least the compiler says nothing about.

Now I have to verify that myfunc is actually assigned to fp and not to vp.

You don't loose anything this way. In your method, you were still
going to have to initialise a void * with a function pointer which is
what the above does (with C99 you can only initialise the first
element of a union).

Of course, you can do it at runtime (mn_mnu.ptr.fp = myfunc;) but then
you can have the menu as const.

Yeah, I want to declare them as constants to save code space.

Thanks again
Marco / iw2nzm

Jul 1 '08 #6
Marco Trapanese ha scritto:
Now I have to verify that myfunc is actually assigned to fp and not to vp.

Verified. Great! It works like a charm.

Marco / iw2nzm
Jul 1 '08 #7
Marco Trapanese <ma************ ******@gmail.co mwrites:
Ben Bacarisse ha scritto:
>(1) Use C99 designated initialiser syntax:

{ .fp = myfunc }

This one doesn't work. I bet Dynamic C is not C99 compliant.
Shame. This is one of the nice part of C99.
>(2) Let the compiler complain about the type-mismatch (if it works):

{ myfunc }

(3) Convert to void * (again, if that is permitted):

{ (void *)myfunc }

These works, or at least the compiler says nothing about.

Now I have to verify that myfunc is actually assigned to fp and not
to vp.
You do realise that they are, in effect, one and the same? You can't
have both fp and vp assigned different values at the same time. That
is what the union is for.

--
Ben.
Jul 1 '08 #8
Ben Bacarisse ha scritto:
You do realise that they are, in effect, one and the same? You can't
have both fp and vp assigned different values at the same time. That
is what the union is for.

You're right again. I didn't realized that. But now I should have
understood: all union items share the same address so they are "the
same" thing.

Ok, I learned something new today :)

Marco / iw2nzm

Jul 1 '08 #9
Marco Trapanese <ma************ ******@gmail.co mwrites:
Ben Bacarisse ha scritto:
You do realise that they are, in effect, one and the same? You can't
have both fp and vp assigned different values at the same time. That
is what the union is for.

You're right again. I didn't realized that. But now I should have
understood: all union items share the same address so they are "the
same" thing.
[...]

Well, sort of. They're not really "the same" thing; they're different
things that happen to share the same space.

Imagine that you work the day shift, and you share an office with
someone who works the night shift. You're never in the office at the
same time. You both have the same address, but you're two different
people. And somebody who wants to visit one of you need to know what
time it is to know which one of you to expect.

As for initialization, an ordinary C90-style initializer for a union
simply initializes the first declared member. For example:

int main(void)
{
union foo {
int x;
char *s;
};

union foo obj1 = { 42 }; /* ok, sets obj1.x to 42 */
union foo obj2 = { "hello" }; /* wrong, tries to set x to "hello" */

return 0;
}

C99 lets you choose which member you want to initialize, but since you
apparently want to initialize the first one anyway, you don't need
that feature.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 1 '08 #10

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

Similar topics

12
1584
by: Ken | last post by:
I am familiar with C and Java, I would like to use a style that I have become accustomed to in Java with C++ but each time I do this I have name conflict. In the past I have just worked around it by using different names can anyone tell me how to get the following to work: I want to have a class named v3d (vector 3d), it has the following private instance variables... float x, y, z; It has the following public get and set methods:
193
9656
by: Michael B. | last post by:
I was just thinking about this, specifically wondering if there's any features that the C specification currently lacks, and which may be included in some future standardization. Of course, I speak only of features in the spirit of C; something like object-orientation, though a nice feature, does not belong in C. Something like being able to #define a #define would be very handy, though, e.g: #define DECLARE_FOO(bar) #define...
16
2316
by: junky_fellow | last post by:
According to Section A6.6 Pointers and Integers (k & R) " A pointer to one type may be converted to a pointer to another type. The resulting pointer may cause addressing exceptions if the subject pointer does not refer to an object suitably aligned in storage. It is guaranteed that a pointer to an object may be converted to a pointer to an object whose type requires less or equally strict storage alignment and back again without change;...
48
2185
by: yezi | last post by:
Hi, all: I want to record some memory pointer returned from malloc, is possible the code like below? int memo_index; int i,j; char *tmp; for (i=0;i<10;i++){
4
1663
by: mathieu | last post by:
Hello, I would like implement a nice way to work around the array of references issue in C++. What do usually people do ? Do you maintain a separate factory/pool of elements as part of the API ? So in my example (*) I would need to either : 1. allocate on the heap (and then fragment memory): void fill(A *array) {
1
1923
by: Ted | last post by:
I managed to get it installed OK, along side MS Visual Studio 2005 (with which I received it). During the install, I made sure I installed everything. I have developed a number of applications using MySQL v 5 and PostgreSQL, but I have not worked with MS SQL. Playing with it after installing it, and running through several tutorials, I generally like what I see, but there are a few issues (so far - I am sure others will crop up as...
25
4830
by: al pacino | last post by:
hi , whats the issue with the following declaration, is it correct and what exactly is happening here. int main() { //..... int* ptr=10; // i suppose ptr is pointing to the memory location which stores the value 10.
2
970
by: mabond | last post by:
Hi I want to begin researching methods for a particular problem I have and would welcome some pointers, or info if anyone has had the same issue. At my place of work we have a display of data in the form of a java applet. The data displayed relates to the performance of our workforce but is provided by a third party and is only seen by us on screen. In other words there is no raw data file received and no means of "ftp" to access the...
8
1423
by: John Nagle | last post by:
The Python documentation for "str" says "str() : Return a string containing a nicely printable representation of an object." However, there's no mention of the fact that "str" of a Unicode string with non-ASCII characters will raise a conversion exception. The documentation (and several Python books) seem to indicate that "str" will produce some "printable representation" for anything, not raise an exception. I know, it was proposed...
0
9707
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, 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...
0
9585
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,...
0
10586
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, 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...
0
10338
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10323
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,...
0
10082
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
4301
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
2
3823
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2997
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.