473,659 Members | 2,922 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

undefined behavior in "macro-based" single-linked list impl...

I was wondering if the 'SLINK_*' and 'SLIST_*' macros, which
implement a simple singly-linked list, will produce _any_ possible
undefined behavior:
_______________ _____________

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

/* Single-Link API
_______________ _______________ ______*/
typedef struct slink_s slink;

struct slink_s {
slink* next;
};

#define SLINK_STATICINI T() {0}

#define SLINK_GET_NEXT( mp_this) ( \
(mp_this)->next \
)

#define SLINK_SET_NEXT( mp_this, mp_link) ( \
(mp_this)->next = (mp_link) \
)

/* Single-List API
_______________ _______________ ______*/
typedef struct slist_s slist;

struct slist_s {
slink front;
};

/* static init */
#define SLIST_STATICINI T() { \
SLINK_STATICINI T() \
}

/* returns the front of the list */
#define SLIST_GET_FRONT (mp_this) ( \
SLINK_GET_NEXT( &(mp_this)->front) \
)

/* returns the mp_link parameter */
#define SLIST_PUSH_FRON T(mp_this, mp_link) ( \
SLINK_SET_NEXT( mp_link, SLIST_GET_FRONT (mp_this)), \
SLINK_SET_NEXT( &(mp_this)->front, mp_link) \
)

/* returns 0 on failure */
#define SLIST_POP_FRONT (mp_this, mp_plink) ( \
*(mp_plink) = SLIST_GET_FRONT (mp_this), \
*(mp_plink) \
? SLINK_SET_NEXT( &(mp_this)->front, \
SLINK_GET_NEXT( *(mp_plink))), 1 \
: 0 \
)

/* Test Application
_______________ _______________ ______*/
#define TEST_DEPTH() 5

static int exit_prompt(int const, char const* const);
static slist g_list = SLIST_STATICINI T();
int main(void) {
int t;
for(t = 0; t < TEST_DEPTH(); ++t) {
int i;
slink* _this;
#define LIST_DEPTH() (t + 5)

for(i = 0; i < LIST_DEPTH(); ++i) {
slink* cmp = 0;
_this = malloc(sizeof(* _this));
cmp = SLIST_PUSH_FRON T(&g_list, _this);
printf("(%p/%p/%p)-SLIST_PUSH_FRON T(...)\n",
(void*)_this,
(void*)SLIST_GE T_FRONT(&g_list ),
(void*)SLINK_GE T_NEXT(_this));
assert(_this == cmp);
}
printf("(%i)-FILLED! Press <ENTERTo Continue...\n", t);
getchar();
_this = SLIST_GET_FRONT (&g_list);
while(_this) {
printf("(%p)-SLIST_GET_FRONT (...)\n", (void*)_this);
_this = SLINK_GET_NEXT( _this);
}
printf("(%i)-ITERATED! Press <ENTERTo Continue...\n", t);
getchar();
while(SLIST_POP _FRONT(&g_list, &_this)) {
printf("(%p)-SLIST_POP_FRONT (...)\n", (void*)_this);
free(_this);
}
printf("(%i)-FLUSHED! Press <ENTERTo Continue...\n", t);
getchar();

puts("\n----------------------------------");
}

assert(! SLIST_GET_FRONT (&g_list));

return exit_prompt(
0, "\n\n\n\
_______________ ________\npress <ENTERto exit...\n");
}
int exit_prompt(int const status, char const* const buf) {
printf("%s", buf);
getchar();
return status;
}

_______________ _____________

Thank you in advance.
Sep 27 '07 #1
2 2168
"Chris Thomasson" <cr*****@comcas t.netwrote in message
news:9K******** *************** *******@comcast .com...
>I was wondering if the 'SLINK_*' and 'SLIST_*' macros, which implement a
simple singly-linked list, will produce _any_ possible undefined behavior:
Sorry for any copy-and-paste errors; here is a link to the code in question:
_______________ _____________
http://appcore.home.comcast.net/misc/macro-slist-c.html
_______________ _____________

:^0

Sep 27 '07 #2
Chris Thomasson wrote On 09/27/07 05:59,:
"Chris Thomasson" <cr*****@comcas t.netwrote in message
news:9K******** *************** *******@comcast .com...
>>I was wondering if the 'SLINK_*' and 'SLIST_*' macros, which implement a
simple singly-linked list, will produce _any_ possible undefined behavior:


Sorry for any copy-and-paste errors; here is a link to the code in question:

>>_____________ _______________


http://appcore.home.comcast.net/misc/macro-slist-c.html
The macros look all right to me. SLIST_POP_FRONT
could be streamlined a bit, but I think it's correct.
They're not safe if the arguments have side-effects:

SLIST_PUSH_FRON T(list, getAnotherNode( ));
or
slist half[2] = { SLIST_STATICINI T(), SLIST_STATICINI T() };
int which = 1;
/* Divide the input nodes among the two lists: */
while ((node = getAnotherNode( )) != NULL)
SLIST_PUSH_FRON T(half[ which ^= 1 ], node);

It's a shame that SLIST_POP_FRONT needs an auxiliary
output variable. I can sympathize with the desire to move
the success/failure indication "out of band," but in this
case it seems clumsy. NULL is a widely-understood "failure"
value for many pointer-related things, and would not be a
stylistic shock to anyone. SLIST_POP_FRONT already uses
the nullness of the link to detect end-of-list; why not
let the user do the same?

It's too bad that SLINK_SET_NEXT and SLINK_GET_NEXT
differ by only one letter, buried in the middle of the
names. Fortunately, their argument counts are different,
so the compiler will holler if/when somebody mixes them up.

It'd be Really Ugly to use these macros with nodes
that can inhabit multiple lists simultaneously. Sparse
matrices, for example, where each node might be linked
in both a row list and a column list:

struct cell {
int row, col;
double value;
slink nextinrow;
slink nextincol;
};

Navigating such a setup will find you using offsetof()
and casts more heavily than is healthy. (True, the matrix
as a whole is not a "simple singly-linked list." But its
rows and columns are when viewed separately, and it's a
shame that the macros make them hard to manipulate.)

If I were going to do something like this, I think
I'd use functions instead of macros: all the side-effect
safety issues disappear, it's easy to add sanity-checking
in debug builds, and so on. Also, you gain some type
safety: SLINK_GET_NEXT will work quite happily with any
pointer to a struct or union with a `next' member, even
if that pointer is not an `slink*'. Compilers are pretty
good at expanding simple functions in-line, especially if
given C99's `inline' hint.

--
Er*********@sun .com
Sep 27 '07 #3

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

Similar topics

188
17316
by: infobahn | last post by:
printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */
40
7857
by: Dave Hansen | last post by:
Please note crosspost. Often when writing code requiring function pointers, it is necessary to write functions that ignore their formal parameters. For example, a state machine function might take a status input, but a certain error-handling state might ignore it: typedef void (*State_Fn)(uint8_t); void error_state(uint8_t status)
3
14453
by: xudeutsch | last post by:
I have such a block in C++ #pragma pack(push,4) #define STATE_NULL 0x0000 #pragma pack(pop) and I need to convert it to C#. I want to use the "MarshalAs" attribute, but i dont know which UnmanagedType that hex value belongs to.
47
46175
by: sudharsan | last post by:
Hi could you please explain wat atoi( ) function is for and an example how to use it?
21
4953
by: Marius Lazer | last post by:
Is it possible to write a macro that single-quotes its argument? #define SOME_MACRO(x) such that SOME_MACRO(foo) expands to 'foo' Thanks, Marius
15
2422
by: rover8898 | last post by:
Hello all, I used setjmp() in a recent of program of mine (it is not completed, so I have not the chance to test it out yet). I am not very profocient in C coding as are some of my co-workers. They (my co-workers) say (with vehement ardor ;) ) that the usage of setjmp() emplyoyed in function"C" that was called from function "B" that was called from function "A" that was called form the main(), will cause havoc in the stack. And it makes...
0
5716
Boxcar74
by: Boxcar74 | last post by:
Hi Everybody!!! I have an Issue. I have an Excel file that queries an Access db. I’m trying to have it so I don’t have to keep updating it manually everyday and save it to a network drive with the file name coming from a cell reference and the current date. What I’ve done have the Excel file open via a Batch file and on “Workbook_Open” I run a few macro to refresh the data then remake and save it to the network drive. My...
9
4086
by: anon.asdf | last post by:
In terms of efficieny: Is it better to use multiple putchar()'s after one another as one gets to new char's OR is it better to collect the characters to a char-array first, and then use puts() to print to screen ????
4
2122
by: Gestorm | last post by:
Hi all, I found a macro "USE_VAR" in the code of bash-3.2 as follows: /*file: bash-3.2/shell.c*/ 344 USE_VAR(argc); 345 USE_VAR(argv); 346 USE_VAR(env); 347 USE_VAR(code); 348 USE_VAR(old_errexit_flag); 349 #if defined (RESTRICTED_SHELL) 350 USE_VAR(saverst);
3
23040
by: Kappucino XL | last post by:
Hi There.. What is the Macro or Code Builder Event, For Copying And Pasting. i.e: I need to click on a field in a textbox, and it must be copied jus by clicking on it. Then I want to click on an empty textbox, and the field I copied must get pasted... How do I go About doing this? XL
0
8428
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
8747
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
8528
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
8627
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
6179
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5649
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();...
0
4175
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...
0
4335
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1737
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.