Promoting unsigned long int to long int

K

Keith Thompson

pereges said:
Thanks for the clarification. After reading this, I guess I will
continue using unsigned long for all the 3 situations.

Um, why? It will probably work, but for case 1 size_t is exactly the
right type, and for case 2 it's guaranteed to work, while unsigned
long isn't.

It sounds like you want to use unsigned long if at all possible, and
use size_t only if it's absolutely necessary. Why is that?
 
P

pereges

Um, why? It will probably work, but for case 1 size_t is exactly the
right type, and for case 2 it's guaranteed to work, while unsigned
long isn't.

It sounds like you want to use unsigned long if at all possible, and
use size_t only if it's absolutely necessary. Why is that?

Mainly because my project has grown beyond 1000 lines and now its
becoming more and more difficult to keep track of things. That's why I
wanted to keep things a little consistent.
 
P

pereges

btw can i sort an array of pointers with qsort function ?? I tried the
following but failed miserably as it reutrned the same unsorted list :


int cmp_coord_x(const void *vpa, const void *vpb)
{
const vector *va = vpa;
const vector *vb = vpb;

return (va->coord said:
coord[0]);
}

int cmp_coord_y(const void *vpa, const void *vpb)
{
const vector *va = vpa;
const vector *vb = vpb;

return (va->coord said:
coord[1]);
}

int cmp_coord_z(const void *vpa, const void *vpb)
{
const vector *va = vpa;
const vector *vb = vpb;

return (va->coord said:
coord[2]);
}

/* axis is used as criterion on how we sort the array */
if (axis == 0)
{
qsort(parent_vpa, sizeof parent_vpa/ sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord_x);
}
if (axis == 1)
{
qsort(parent_vpa, sizeof parent_vpa/ sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord_y);
}
if (axis == 2)
{
qsort(parent_vpa, sizeof parent_vpa/ sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord_z);
}
 
B

Ben Bacarisse

pereges said:
btw can i sort an array of pointers with qsort function ??

Yes, you can.
I tried the
following but failed miserably as it reutrned the same unsorted list :


int cmp_coord_x(const void *vpa, const void *vpb)
{
const vector *va = vpa;
const vector *vb = vpb;

The array is an array of vector *. The void * you get in the compare
points to an array element -- it is a void * but it points to a vector
**. This is in the FAQ. If you don't mind a cast:

const vector *va = *(const vector *const *)vpa;
const vector *vb = *(const vector *const *)vpb;
return (va->coord[0] < va->coord[0] ? -1 : vb->coord[0] > vb->coord[0]);

You have your va's and vb's mixed up. I think you wanted:

return (va->coord said:
}

int cmp_coord_y(const void *vpa, const void *vpb)
{
const vector *va = vpa;
const vector *vb = vpb;

return (va->coord said:
coord[1]);
}

int cmp_coord_z(const void *vpa, const void *vpb)
{
const vector *va = vpa;
const vector *vb = vpb;

return (va->coord said:
coord[2]);
}

/* axis is used as criterion on how we sort the array */
if (axis == 0)
{
qsort(parent_vpa, sizeof parent_vpa/ sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord_x);
}
if (axis == 1)
{
qsort(parent_vpa, sizeof parent_vpa/ sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord_y);
}
if (axis == 2)
{
qsort(parent_vpa, sizeof parent_vpa/ sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord_z);
}

I'd use an array of function pointers and write:

qsort(parent_vpa, sizeof parent_vpa / sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord[axis]);

the array would be:

typedef int compare_function(const void *, const void *);
compare_function *cmp_coord[] = {
cmp_coord_x, cmp_coord_y, cmp_coord_z
};

(not compiled so beware syntax errors).
 
J

Jens Thoms Toerring

pereges said:
On Jun 30, 8:47 pm, (e-mail address removed) (Jens Thoms Toerring) wrote:

btw its still not working. I'm not sure why but I had to use long
instead of unsigned long to make it work.

I just tried to boil down your function for a simpler case, i.e.
sorting an array of integers instead of an array of pointers to
some structures. And when doing that the program crashed since
there seems to be an infinite recursion. I don't have the time
at the moment to digg further into this but you may want to check
the algorithm carefully. Perhaps also have a look at the imple-
mentation of qsort in K&R2...
Regards, Jens
 
B

Barry Schwarz

Suppose I have a structure:

struct mesh
{
unsigned long nvert; /* number of vertices */
unsigned long ntri; /* number of triangles */
vector *vert; /* pointer to array of vertices */
triangle *tri; /* pointer to array of triangles */
};

Now, according to what you are saying nvert and ntri should have data
type size_t instead. In my program its possible for nvert and ntri to
be in millions. I have been adviced that size_t in many cases causes
loss of data, hence I'm skecptical about its use. Also, I would want
to keep things consistent.

SIZE_MAX can be as small as 65K while ULONG_MAX must be at least 4G.
Check your system, or your portability goals, to determine if this a
concern.


Remove del for email
 
B

Barry Schwarz

Hello, I'm trying to sort an array of pointers based on the values
they point to. I'm using the quick sort method. The array of pointers

All of which begs the question - why not use qsort which can sort an
array of pointers just fine given the correct compare function?

snip


Remove del for email
 
P

pereges

When I count nodes in linked list, I use long unsigned.
The number of nodes that malloc can generate,
isn't related to size_t.

What if I had to create a link list of pointers to an array ? In that
case the number of nodes in link list can also be size_t. I think you
can apply to a lot of cases by careful analysis.
 
P

pereges

Yes, you can.
You have your va's and vb's mixed up. I think you wanted:

return (va->coord[0] < vb->coord[0] ? -1 : va->coord[0] > vb->coord[0]);

I'd use an array of function pointers and write:

qsort(parent_vpa, sizeof parent_vpa / sizeof *parent_vpa,
sizeof *parent_vpa, cmp_coord[axis]);

the array would be:

typedef int compare_function(const void *, const void *);
compare_function *cmp_coord[] = {
cmp_coord_x, cmp_coord_y, cmp_coord_z
};

(not compiled so beware syntax errors).

Thanks.
 
P

pereges

Sure.
I also use long unsigned to count lines in a text stream.

Using long unsigned for lines in text stream is different i guess
because its not related to size_t in anyway. In my case, I'm building
a kdtree for 3d mesh where I have a max_triangles entity which
represents teh threshold of maximum number of triangles that can be
inside a kdtree node. At the most there can be all triangles in the kd
tree node(i.e. the root node) but since number of triangles (ntri, it
was also used to allocate memory for triangle list) was declared as
size_t, I have declared max_triangles also has size_t because it can
take atmost the value ntri.
 
P

pereges

btw what is appropriate format specifer for size_t type variable ? It
has no problems with any type of integer format specifers( %d %i %lu
%u etc)
 
J

Joachim Schmitz

pereges said:
btw what is appropriate format specifer for size_t type variable ? It
has no problems with any type of integer format specifers( %d %i %lu
%u etc)
%z in C99, %lu and a cast (unsigned long) in C89

Bye, Jojo
 
P

pereges

...
size_t a
...
printf("a=%lu\n", (unsigned long)a);
...
I think you meant (unsigned long)&a ?

But why is this caste needed when you are already using %lu ? Often
when I want to use chars as ints, I don't use any caste. I simply do :

char a;
scanf("%d", &a);

And it works.
 
J

Joachim Schmitz

pereges said:
I think you meant (unsigned long)&a ?
No! To print the address of a use %p
But why is this caste needed when you are already using %lu ? Often
%lu tells printf to expect a long unsigned valie and read it off the stack
(or whatever the parameter passing method of you implementation might be), a
is a size_t which may or may not be the same size, but printf doesn't know,
so it grabs an unsigned long and possible touches something that isn't
allowew or supposed to touch.
when I want to use chars as ints, I don't use any caste. I simply do :

char a;
scanf("%d", &a);

And it works.
%d expects an int, so the scanf reads an int and places it in a char, loos
of precision and sign may occur.

Bye, Jojo
 
P

pereges

No! To print the address of a use %p


%lu tells printf to expect a long unsigned valie and read it off the stack
(or whatever the parameter passing method of you implementation might be), a
is a size_t which may or may not be the same size, but printf doesn't know,
so it grabs an unsigned long and possible touches something that isn't
allowew or supposed to touch.




%d expects an int, so the scanf reads an int and places it in a char, loos
of precision and sign may occur.

I'm sorry I mean while scanning a not printing it :

size_t a;
scanf("%lu", &a);

Is this operation correct ?
 
V

vippstar

%d expects an int, so the scanf reads an int and places it in a char, loos
of precision and sign may occur.
That's wrong - it actually invokes undefined behavior.
If you want to do that try
signed char a;
scanf("%hhd", &a);

Recently I learned that this:
int i;
scanf("%d", &i);
invokes undefined behavior with overflow. (ie inputs that their result
INT_MAX or < INT_MIN)
It's unclear to me if this also happends to signed char, but if that
is the case, scanf("%hhd", &a); is potentially invoking undefined
behavior. It's beyond me WHY scanf() is so stupid.
 
V

vippstar

size_t a;
scanf("%lu", &a);

Is this operation correct ?

With C99, the appropriate way is this:
size_t a;
int i = scanf("%zu", &a);
/* inspect i's value */
With C89 look at pete's reply.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top