473,387 Members | 1,585 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

about ## in ANSI C

Dear,

could you tell me about the usage of "##" in preprossor

give me some simple examples.

thanks.

I just got the example from "dissection C" as follows:

#define X(i) x ## i
X(1)=X(2)=X(3);
==>
x1 = x2 = x3;

I can hardly make sense.

--
Nov 14 '05 #1
3 1923
On 2004-04-09, J Wang <cs****@bath.ac.uk> wrote:
could you tell me about the usage of "##" in preprossor

give me some simple examples.

thanks.

I just got the example from "dissection C" as follows:

#define X(i) x ## i
X(1)=X(2)=X(3);
==>
x1 = x2 = x3;

I can hardly make sense.


It is the preprocessor's "paste" operator. It concatenates the
preprocessing token on its left to the preprocessing token on its
right.

Also read the answer to question 10.20 of the C-faq.

http://www.eskimo.com/~scs/C-faq/top.html

-- James
Nov 14 '05 #2
J Wang wrote:
could you tell me about the usage of "##" in preprossor

give me some simple examples.


e.g. http://gcc.gnu.org/onlinedocs/gcc-3....atenation.html

Nov 14 '05 #3
cs****@bath.ac.uk (J Wang) wrote in message news:<Hv*************@bath.ac.uk>...
Dear,

could you tell me about the usage of "##" in preprossor

give me some simple examples.

thanks.

I just got the example from "dissection C" as follows:

#define X(i) x ## i
X(1)=X(2)=X(3);
==>
x1 = x2 = x3;

I can hardly make sense.

--


This is an implementation of a C++-ish standard header in C. The token
pasting makes it look ugly, and the reserved identifiers all over the
place uglier still, but it is what it is.

Gregory Pietsch

/* dynarray.h - dynamic array header

AUTHOR: Gregory Pietsch

This is an implementation of dynamic arrays of an unknown type.
This example assumes the following macros are defined:

T - the type of an array element. The only restriction on the
type is that it needs to be turned into a pointer by
postpending a *
TS - a "slug" prefix for all the functions in the library
and the array type
Tctor(x) - a function that initializes a T for use after malloc()ing
it. In other words, a constructor if I were using C++
Tdtor(x) - a destructor function, analagous to Tctor
Tassign(x,y) - An assignment function that assigns x to y. Both
elements are pointers to the actual elements

*/

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

#define _VAL(y,x) y ## x
#define _NM(y,x) _VAL(y,x)

#ifndef CAPACITY_DEFINED
#define CAPACITY_DEFINED
typedef enum capacity
{
default_size,
reserve
} capacity;
#endif

#ifdef PROTOS_ONLY

/* types */

typedef struct _NM (TS, _ARRAY_T)
{
T *_Ptr;
size_t _Len, _Res;
} _NM (TS, _ARRAY_T);

_NM (TS, _ARRAY_T) * _NM (TS, _create) (void);
void
_NM (TS, _destroy) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _ctor) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _ctor_with_size) (_NM (TS, _ARRAY_T) *, size_t,
capacity);
void
_NM (TS, _copy_ctor) (_NM (TS, _ARRAY_T) *, _NM (TS, _ARRAY_T)
*);
void
_NM (TS, _ctor_from_ptr) (_NM (TS, _ARRAY_T) *, T *, size_t);
void
_NM (TS, _dtor) (_NM (TS, _ARRAY_T) *);
_NM (TS, _ARRAY_T) * _NM (TS, _append) (_NM (TS, _ARRAY_T) *, T *,
size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _assign) (_NM (TS, _ARRAY_T) *, T *,
size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _insert) (_NM (TS, _ARRAY_T) *, size_t,
T *,
size_t, size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _remove) (_NM (TS, _ARRAY_T) *, size_t,
size_t);
_NM (TS, _ARRAY_T) * _NM (TS, _subarray) (_NM (TS, _ARRAY_T) *,
_NM (TS, _ARRAY_T) *,
size_t,
size_t);
void
_NM (TS, _swap) (_NM (TS, _ARRAY_T) *, _NM (TS, _ARRAY_T) *);
T *
_NM (TS, _get_at) (_NM (TS, _ARRAY_T) *, size_t);
void
_NM (TS, _put_at) (_NM (TS, _ARRAY_T) *, size_t, T *);
T *
_NM (TS, _base) (_NM (TS, _ARRAY_T) *);
size_t
_NM (TS, _length) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _resize) (_NM (TS, _ARRAY_T) *, size_t, T *);
size_t
_NM (TS, _reserve) (_NM (TS, _ARRAY_T) *);
void
_NM (TS, _set_reserve) (_NM (TS, _ARRAY_T) *, size_t);

#else

#ifndef Tctor
#define Tctor(x)
#endif
#ifndef Tdtor
#define Tdtor(x)
#endif
#ifndef Tassign
#define Tassign(x,y) (*(x) = *(y))
#endif

/* functions */

static void Nomemory (void)
{
fputs ("No memory\n", stderr);
abort ();
}

static void _NM (TS, _Xinv) (void)
{
fputs ("Invalid dynamic array argument\n", stderr);
abort ();
}

static void _NM (TS, _Xlen) (void)
{
fputs ("Length error: dynamic array too long\n", stderr);
abort ();
}

static void _NM (TS, _Xran) (void)
{
fputs ("Out of range: invalid dynamic array position\n", stderr);
abort ();
}

static void _NM (TS, _Tidy) (_NM (TS, _ARRAY_T) * this, int
_Constructed)
{
size_t i;

if (_Constructed && this->_Ptr != 0)
{
for (i = 0; i < this->_Len; i++)
Tdtor (this->_Ptr + i);
free (this->_Ptr);
}
this->_Len = 0;
this->_Ptr = 0;
this->_Res = 0;
}

static void _NM (TS, _Grow) (_NM (TS, _ARRAY_T) * this, size_t _N, T *
_S,
int _Trim)
{
size_t _Os = this->_Ptr == 0 ? 0 : this->_Res;
size_t _I, _M, _R;
T *_Np;

if (_N == 0)
{
if (_Trim)
_NM (TS, _Tidy) (this, 1);
}
else if (_N == _Os || _N < _Os && !_Trim);
else
{
_M = this->_Ptr == 0 && _N < this->_Res ? this->_Res : _N;
_Np = calloc (_M, sizeof (T));
if (_Np == 0)
Nomemory (); /* no memory */
for (_I = 0; _I < _M; _I++)
Tctor (_Np + _I);
_R = _M;
_M = _N < this->_Len ? _N : this->_Len;
for (_I = 0; _I < _M; ++_I)
Tassign (_Np + _I, this->_Ptr + _I);
if (_S != 0)
for (; _I < this->_Res; ++_I)
Tassign (_Np + _I, _S);
_NM (TS, _Tidy) (this, 1);
this->_Ptr = _Np;
this->_Res = _R;
}
this->_Len = _N;
}

/* Create a dynamic array from the void. */
_NM (TS, _ARRAY_T) * _NM (TS, _create) (void)
{
_NM (TS, _ARRAY_T) * x = malloc (sizeof (_NM (TS, _ARRAY_T)));

if (x == 0)
Nomemory ();
_NM (TS, _Tidy) (x, 0);
return x;
}

/* Completely return a dynamic array to the void. */
void _NM (TS, _destroy) (_NM (TS, _ARRAY_T) * x)
{
_NM (TS, _Tidy) (x, 1);
free (x);
}

/* Construct a previously allocated array. */
void _NM (TS, _ctor) (_NM (TS, _ARRAY_T) * this)
{
_NM (TS, _Tidy) (this, 0);
}

/* Construct an array with a reserve or default size. */
void _NM (TS, _ctor_with_size) (_NM (TS, _ARRAY_T) * this, size_t n,
capacity c)
{
_NM (TS, _Tidy) (this, 0);
this->_Res = n;
if (c == default_size)
_NM (TS, _Grow) (this, n, 0, 0);
}

/* Copy constructor - construct an array that is a copy of another
array. */
void _NM (TS, _copy_ctor) (_NM (TS, _ARRAY_T) * this, _NM (TS,
_ARRAY_T) * x)
{
size_t i;

_NM (TS, _Tidy) (this, 0);
_NM (TS, _Grow) (this, _NM (TS, _length) (x), 0, 0);
for (i = 0; i < this->_Len; i++)
Tassign (this->_Ptr + i, x->_Ptr + i);
}

/* Construct an array from a pointer and length. */
void _NM (TS, _ctor_from_ptr) (_NM (TS, _ARRAY_T) * this, T * s,
size_t n)
{
if (s == 0)
_NM (TS, _Xinv) ();
_NM (TS, _Tidy) (this, 0);
_NM (TS, _assign) (this, s, n, 1);
}

/* Destructor. */
void _NM (TS, _dtor) (_NM (TS, _ARRAY_T) * this)
{
_NM (TS, _Tidy) (this, 1);
}

/* Append an array to a dynamic array. */
_NM (TS, _ARRAY_T) * _NM (TS, _append) (_NM (TS, _ARRAY_T) * this, T *
_S,
size_t _N, size_t _D)
{
size_t _I;

if (NPOS - this->_Len <= _N)
_NM (TS, _Xlen) ();
_I = this->_Len;
for (_NM (TS, _Grow) (this, _N += _I, 0, 0); _I < _N; ++_I, _S +=
_D)
Tassign (this->_Ptr + _I, _S);
return this;
}

/* Assign an array to a dynamic array. */
_NM (TS, _ARRAY_T) * _NM (TS, _assign) (_NM (TS, _ARRAY_T) * this, T *
_S,
size_t _N, size_t _D)
{
size_t _I;

_NM (TS, _Grow) (this, _N, 0, 1);
for (_I = 0; _I < _N; ++_I, _S += _D)
Tassign (this->_Ptr + _I, _S);
return this;
}

/* Insert an array into a dynamic array at position _P. */
_NM (TS, _ARRAY_T) * _NM (TS, _insert) (_NM (TS, _ARRAY_T) * this,
size_t _P,
T * _S, size_t _N, size_t _D)
{
size_t _I;

if (this->_Len < _P)
_NM (TS, _Xran) ();
if (NPOS - this->_Len <= _N)
_NM (TS, _Xlen) ();
if (0 < _N)
{
_I = this->_Len - _P;
for (_NM (TS, _Grow) (this, _N + this->_Len, 0, 0); 0 < _I;)
{
--_I;
Tassign (this->_Ptr + (_P + _N + _I), this->_Ptr + (_P +
_I));
}
for (_I = 0; _I < _N; ++_I, _S += _D)
Tassign (this->_Ptr + (_P + _I), _S);
}
return this;
}

/* Remove _N elements from the array at position _P. */
_NM (TS, _ARRAY_T) * _NM (TS, _remove) (_NM (TS, _ARRAY_T) * this,
size_t _P,
size_t _N)
{
size_t _M, _I;

if (this->_Len < _P)
_NM (TS, _Xran) ();
if (this->_Len - _P < _N)
_N = this->_Len - _P;
if (0 < _N)
{
_M = this->_Len - _P - _N;
for (_I = 0; _I < _M; ++_I)
Tassign (this->_Ptr + (_P + _I), this->_Ptr + (_P + _I + _N));
_NM (TS, _Grow) (this, this->_Len - _N, 0, 0);
}
return this;
}

/* Assign _X to a subarray of this starting at position _P with length
_N. If this and _X are the same pointer, handle it via removing the
elements. */
_NM (TS, _ARRAY_T) * _NM (TS, _subarray) (_NM (TS, _ARRAY_T) * this,
_NM (TS, _ARRAY_T) * _X,
size_t _P,
size_t _N)
{
if (this->_Len < _P)
_NM (TS, _Xran) ();
if (this->_Len - _P < _N)
_N = this->_Len - _P;
return this == _X ? (_NM (TS, _remove) (this, _P + _N, NPOS),
_NM (TS, _remove) (this, 0, _P))
: _NM (TS, _assign) (_X, this->_Ptr + _P, _N, 1);
}

/* Swap the contents of two arrays. */
void _NM (TS, _swap) (_NM (TS, _ARRAY_T) * this, _NM (TS, _ARRAY_T) *
_X)
{
T *_Tp;
size_t _T;

_Tp = this->_Ptr;
this->_Ptr = _X->_Ptr;
_X->_Ptr = _Tp;
_T = this->_Len;
this->_Len = _X->_Len;
_X->_Len = _T;
_T = this->_Res;
this->_Res = _X->_Res;
_X->_Res = _T;
}

/* Get an element of the array. */
T *_NM (TS, _get_at) (_NM (TS, _ARRAY_T) * this, size_t _I)
{
if (this->_Len <= _I)
_NM (TS, _Xran) ();
return this->_Ptr + _I;
}

/* Put an element at a specific position in the array. If _I is one
past
the length of the array, handle it. */
void _NM (TS, _put_at) (_NM (TS, _ARRAY_T) * this, size_t _I, T * _X)
{
if (this->_Len < _I)
_NM (TS, _Xran) ();
else if (this->_Len == _I)
_NM (TS, _append) (this, _X, 1, 1);
else
Tassign (this->_Ptr + _I, _X);
}

/* Get the base of the array. */
T *_NM (TS, _base) (_NM (TS, _ARRAY_T) * this)
{
return this->_Len != 0 ? this->_Ptr : 0;
}

/* Get the length of the array. */
size_t _NM (TS, _length) (_NM (TS, _ARRAY_T) * this)
{
return this->_Len;
}

/* Resize the array. */
void _NM (TS, _resize) (_NM (TS, _ARRAY_T) * this, size_t _N, T * _X)
{
_NM (TS, _Grow) (this, _N, _X, 1);
}

/* Get the number of elements that are reserved. */
size_t _NM (TS, _reserve) (_NM (TS, _ARRAY_T) * this)
{
return this->_Res;
}

/* Set the number of elements that are reserved. This only works on
an
array with no elements in it. */
void _NM (TS, _set_reserve) (_NM (TS, _ARRAY_T) * this, size_t _R)
{
if (this->_Ptr == 0)
this->_Res = _R;
}

#endif

#undef _NM
#undef _VAL

/* END OF FILE */
Nov 14 '05 #4

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

Similar topics

36
by: Bhalchandra Thatte | last post by:
I am allocating a block of memory using malloc. I want to use it to store a "header" structure followed by structs in my application. How to calculate the alignment without making any assumption...
9
by: Tim Rentsch | last post by:
I have a question about what ANSI C allows/requires in a particular context related to 'volatile'. Consider the following: volatile int x; int x_remainder_arg( int y ){ return x % y; }
4
by: Anonymousgoogledeja | last post by:
hi all, while I read the code from linux sources. I read the statement static const struct iw_ioctl_description standard_ioctl = { = { .header_type = IW_HEADER_TYPE_NULL, },
2
by: Ziver MALHASOGLU | last post by:
Hi, I produce a text file using my windows application written with c#. -- System.Text.Encoding encOutput=null; encOutput=System.Text.Encoding.UTF8; StreamWriter sw=new...
11
by: hammad.awan_nospam | last post by:
Hello, I'm wondering if it's possible to do the following with Generics: Let's say I have a generic member variable as part of a generic class like this: List<DLinqQuery<TDataContext>>...
66
by: KimmoA | last post by:
Hey! Some questions about C that have been bugging me for a while... 1) Is inline a valid C keyword or not? I was kind of surprised of not finding it in C, to be honest. My "The C Programming...
127
by: bz800k | last post by:
Hi Does this code satisfy ANSI C syntax ? void function(void) { int a = 2; a = ({int c; c = a + 2;}); /* <<-- here !! */ printf("a=%d\n", a);
9
by: andrew | last post by:
Hi: I use "g++ array.cpp" on freebsd, surprised, the code can be compiled #include <iostream> using namespace std; int getInt() { int a = 10; int b = 2; return a * b; }
0
NeoPa
by: NeoPa | last post by:
ANSI-89 v ANSI-92 Before we get into all the various types of pattern matching that can be used, there are two ANSI standards used for the main types of wildcard matching (matching zero or more...
8
AmberJain
by: AmberJain | last post by:
HELLO, Is it necessary for a C programmer to have an ANSI C standard or it's sufficient to own Kernigham and Rithie's The C programming language? I know that the ritchie's book is quite brief...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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...
0
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,...

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.