473,699 Members | 2,417 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Macro for supplying memset with an unsigned char


I'm trying to come up with a fully-portable macro for supplying memset
with an unsigned char rather than an int. I'm going to think out loud
as I go along. . .

I'll take a sample system before I begin:

CHAR_BIT == 16
sizeof(short) == sizeof(int) == 1
Assume none of the integer types have padding bits
Sign-magnitude

Therefore we have:

UCHAR_MAX == 65535
INT_MIN = -32767
INT_MAX = 32767

Let's say we have an array of bytes and we want to set every byte to
65000. We CANNOT use:

memset(data, 65000, sizeof data);

because the conversion from unsigned integer types to signed integer
types "is implementation-defined or an implementation-defined signal
is raised" if the number is out of range.

Therefore we need to supply memset with an int value, which, went
converted to unsigned char, will yield the value we want.

The rules for converting from signed to unsigned are as follows:

| If the new type is unsigned, the value is converted
| by repeatedly adding or subtracting one more than
| the maximum value that can be represented in the
| new type until the value is in the range of the new type.

The addition method is easier to understand so we'll go with that one.
If we start off with a negative number like -1, then here's what will
happen:

char unsigned c = -1;

is equal to:

infinite_range_ int x = -1; /* Let's pretend we have a signed
int type that can hold any number */

while (0 x || UCHAR_MAX < x) x += UCHAR_MAX +
(infinite_range _int)1;

char unsigned c = x;

So on our own system, this is:

while (0 x || 65535 < x) x += 65536;

Clearly, if x = -1, then it only takes one iteration of the loop to
yield 65535, i.e. UCHAR_MAX.

Therefore, if we want UCHAR_MAX-1, then we'd use (int)-2.
For UCHAR_MAX-2, we'd use (int)-3.

The entire set of data looks something like:

int char unsigned
-1 65535
-2 65534
-3 65533
-4 65532
-5 65531
-6 65530
-7 65529
-8 65528
-9 65527
-10 65526
-11 65525
-12 65524
....
....
-32764 32772
-32765 32771
-32766 32770
-32767 32769
-32768 32768 <--

Now I've just realised a problem. An unsigned char can store 65536
different combinations (i.e. 0 through 65535), but an int can only
store 65535 different combination (i.e. -32767 through 32767) if we're
using something other than two's complement. I don't know what I'll do
about that, but for now I'll try continue with the other two number
systems:

#if NUMBER_SYSTEM != SIGN_MAGNITUDE

#define UC_AS_INT(x) /* Whatever we're going to do */

#endif

My first thought is something like:

#define UC_AS_INT(x) UC_AS_INT_Inter nal( (char unsigned)(x) )

#define UC_AS_INT_Inter nal(x) ( x INT_MAX \
? -(int)(UCHAR_MAX - x) - 1 \
: (int)x )

Anyway it's Friday an I've stuff to do, but if anyone wants to finish
it off then feel free! :)

If we can't get all 65536 combinations out of one's complement or sign-
magnitude, then we can just have a macro that changes it to:

char unsigned *p = data;
char unsigned const *const pover = data + sizeof data;
while (pover != p) *p++ = c;

Martin

Sep 28 '07
12 3578
"Martin Wells" <wa****@eircom. neta écrit dans le message de news:
11************* *********@o80g2 00...legr oups.com...
Army1987:
>If you want to set every byte of an object to a value (other than
0 or a character constant in the basic character set), you know
what that does on that object. And since that depends on the
implementation , why do you want to do it fully-portably?

I'm writing portable code for an embedded system. The microcontroller
will output a byte value via ports consisting of individual pins which
will be either 5 volts or 0 volts to indicate binary 1 or 0. I want to
be easily able to set all ports to a given pattern (e.g. all zeros,
all ones, alternating ones and zeros, two zeros then a one, etc.).

Of course, the code that actually sets the pins values will be
micrcontroller, library and compiler specific, but there's no reason
to deportify the guts of the program.
For the specific cases all bits 0 and all bits 1, the solution is simple:

memset(array, 0, sizeof array); /* all bits 0 */
memset(array, -1, sizeof array); /* all bits 1 */

For arbitrary bit patterns, it may not be possible with memset on
architectures with non twos-complement arithmetics and sizeof(int) == 1.
But discussing these is a form of mental masturbation as they do not exist
in the real world. Most regulars here indulge in it almost daily, but only
in forums like this one, not in production code. Obfuscating calls to
memset to ensure protability to the DS9K is exactly that: obfuscation. It
makes your program harder to write, harder to read, more prone to bugs.

--
Chqrlie.
Oct 1 '07 #11
Chqrlie:
For the specific cases all bits 0 and all bits 1, the solution is simple:

memset(array, 0, sizeof array); /* all bits 0 */
memset(array, -1, sizeof array); /* all bits 1 */

For arbitrary bit patterns, it may not be possible with memset on
architectures with non twos-complement arithmetics and sizeof(int) == 1.

The UC_MEMSET macro takes care of that by calling a function which has
a loop. If you ask me though, the C89 Standard is broken in that it
doesn't provide a UC_MEMSET itself. But the again, it makes more fun
for us to patch over the broken stuff :D

But discussing these is a form of mental masturbation as they do not exist
in the real world. Most regulars here indulge in it almost daily, but only
in forums like this one, not in production code.

Yes I can agree that if time is money, you're not going to be very
productive by accomodating sign-magnitude machines, but it still is a
bit of fun to make your code 100% portable to a certain standard. I'm
doing an embedded systems project at the moment, and most people would
start off as non-portable and keeping getting more and more non-
portable. Instead I've decided to got the portable route... and it's
going well so far :D

Obfuscating calls to
memset to ensure protability to the DS9K is exactly that: obfuscation. It
makes your program harder to write, harder to read, more prone to bugs.

Not if you hide the funky stuff in header files:

#include "broken_int_uc_ fixes.h"

int main(void)
{
UC_MEMSET(whate ver,UCHAR_MAX,s izeof whatever);
}

Martin

Oct 1 '07 #12
"Charlie Gordon" <ne**@chqrlie.o rgwrites:
"Martin Wells" <wa****@eircom. neta écrit dans le message de news:
11************* *********@o80g2 00...legr oups.com...
>Army1987:
>>If you want to set every byte of an object to a value (other than
0 or a character constant in the basic character set), you know
what that does on that object. And since that depends on the
implementatio n, why do you want to do it fully-portably?

I'm writing portable code for an embedded system. The microcontroller
will output a byte value via ports consisting of individual pins which
will be either 5 volts or 0 volts to indicate binary 1 or 0. I want to
be easily able to set all ports to a given pattern (e.g. all zeros,
all ones, alternating ones and zeros, two zeros then a one, etc.).

Of course, the code that actually sets the pins values will be
micrcontroller , library and compiler specific, but there's no reason
to deportify the guts of the program.

For the specific cases all bits 0 and all bits 1, the solution is simple:

memset(array, 0, sizeof array); /* all bits 0 */
memset(array, -1, sizeof array); /* all bits 1 */

For arbitrary bit patterns, it may not be possible with memset on
architectures with non twos-complement arithmetics and sizeof(int) == 1.
But discussing these is a form of mental masturbation as they do not exist
in the real world. Most regulars here indulge in it almost daily, but only
in forums like this one, not in production code. Obfuscating calls to
memset to ensure protability to the DS9K is exactly that: obfuscation. It
makes your program harder to write, harder to read, more prone to
bugs.
Well said.
Oct 1 '07 #13

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

Similar topics

10
6799
by: copx | last post by:
I want to fill char/int arrays with zeros. Is something like this portable/save: char myArray; memset(myArray,0,(30*80) * sizeof(char)); copx
6
8242
by: bob_jenkins | last post by:
{ const void *p; (void)memset((void *)p, ' ', (size_t)10); } Should this call to memset() be legal? Memset is of type void *memset(void *, unsigned char, size_t) Also, (void *) is the generic pointer type. My real question is, is (void *) such a generic pointer type that it
7
2086
by: adelfino | last post by:
I mean: unsigned char foo = ""; is the same as: unsigned char foo; memset (foo, '\0', bar); ?
17
6352
by: Frederick Ding | last post by:
Hi, guys,I met a problem, Please look at the problem below: int* bit = (int*)malloc(10000*sizeof(int)); memset(bit, 1, 10000*sizeof(int)); printf("%d %d %d\n", bit,bit, bit); Output: 16843009 16843009 16843009 Obviously I set the bit to bit to 1, but it outputs are not 1's.
21
8767
by: jacob navia | last post by:
Many compilers check printf for errors, lcc-win32 too. But there are other functions that would be worth to check, specially memset. Memset is used mainly to clear a memory zone, receiving a pointer to the start, the value (most of the time zero) and the size of the memory array to clear. Problems appear when the size given is not the size of the object given as its first argument. For instance void fn(void)
4
5043
by: pauldepstein | last post by:
This is copy-pasted from cplusplus.com: BEGINNING OF QUOTE void * memset ( void * buffer, int c, size_t num ); Fill buffer with specified character. Sets the first num bytes pointed by buffer to the value specified by c parameter
19
7924
by: aaragon | last post by:
Hi everyone. A very simple question. I would like to know what is better in terms of performance. I want to use a simple function to obtain the minimum of two values. One way could be using a macro: #define min(a,b) ((a<b)?a:b) I thought that another way could be to use a template function: template <class T> T min<T a, T b>
12
3907
by: Shhnwz.a | last post by:
Hi, I want to know some of the situations , when to use memcpy() and when to memset(); Thanx in Advance..
9
321
by: Francois Grieu | last post by:
Consider this macro // check if x, assumed of type unsigned char, is in range #define ISVALID(x) ((x)>=0x20 && (x)<=0x7E) Of course, this can't be safely used as in if (ISVALID(*p++)) foo(); where p is a pointer ot unsigned char.
0
8685
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
8613
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
9032
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...
0
8880
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
6532
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
4374
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
4626
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3054
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
3
2008
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.