3 registered members (AndrewAMD, Quad, M_D),
1,217
guests, and 1
spider. |
Key:
Admin,
Global Mod,
Mod
|
|
|
function overloading problems (not working sometimes)
#451438
05/06/15 14:22
05/06/15 14:22
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
OP
Expert
|
OP
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
hi I have a little problem when using function overloading: when passing different types of pointers as parametrs, sometimes the one with char* is used instead of the one with short*, sometimes the one with var* is used instead of the one with int*, even if the type of other parameters differ. here are the little examples: here char* is used instead of short* (originally both bytevalue were char, but it is wrong with char and short too)
void array_fillbytes(char* arrayin, int arraylength, char bytevalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
memset(arrayin, bytevalue, sizeof(char) * arraylength);
}
void array_fillbytes(short* arrayin, int arraylength, short bytevalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
memset(arrayin, (char)bytevalue, sizeof(short) * arraylength);
}
it does not work properly even if I add an int or var fake parameters respectively in the end, always the one with var* is used:
void ShowArrayElements(int* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_int(NULL, inarray[i]), posx, posy + i*20, COLOR_RED );
}
}
void ShowArrayElements(var* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_num(NULL, inarray[i]), posx, posy + i*20, COLOR_GREEN );
}
}
in this case only char* is used instead of the short*, all others are fine:
void array_fill(char* arrayin, int arraylength, char elementvalue);
void array_fill(short* arrayin, int arraylength, short elementvalue);
void array_fill(int* arrayin, int arraylength, int elementvalue);
void array_fill(var* arrayin, int arraylength, var elementvalue);
void array_fill(VECTOR* arrayin, int arraylength, VECTOR* elementvalue);
do I do something totally wrong, or the lite-c compiler is playing with me? I can make workarounds of course, I just want to get more, more, and more knowledge (or engine bugs)
|
|
|
Re: function overloading problems (not working sometimes)
[Re: sivan]
#451439
05/06/15 14:52
05/06/15 14:52
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
I would say the type deduction is failing you there. But why rely on that anyway, you may end up with wrong pointer types anyway. A better solution would be this:
void array_fill(void *arrayin, int arraylength, char elementvaluem int elementSize);
{
if(!arrayin || arraylength <= 0)
return;
memset(arrayin, bytevalue, elementSize * arraylength);
}
(You indentation is seriously trippy though. You may want to adopt indentation with tabs and alignment with spaces in the future so it looks universally consistent)
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
Re: function overloading problems (not working sometimes)
[Re: WretchedSid]
#451440
05/06/15 14:54
05/06/15 14:54
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
i like to use one of two methods ,even in c++ even though i dont have to , and to accomplish both , i use char* instead of adding more code for types or whatever. method 1: i pack all functions in to one
//in lite-c i used such a similir function
void place_entity(ENTITY* my_ent,char* my_type)
{
if(str_cmp(my_type,"a big rock"))
{
}
if(str_cmp(my_type,"a small rock"))
{
}
if(str_cmp(my_type,"a tree"))
{
}
}
...
place_entity(me,"a big rock");
place_entity(me,"a tree");
and method 2: a dispatcher function , it dispatches other functions
//in c++ i used this for a thread dispatcher ,same concept
void thread_dispatcher(const char* task,void* task_packet,void* second_task_packet)
{
if(m_navbuilder)
{
if(strcmp(task,"build the navmesh")==0)
{
custombuild* build_settings=(custombuild*)task_packet;
m_navbuilder->Nav_From_Custombuild(build_settings);
}
if(strcmp(task,"load the navmesh")==0)
{
char* filename=(char*)task_packet;
m_navbuilder->load_all_tiles((char*)filename);
}
if(strcmp(task,"save the navmesh")==0)
{
char* filename=(char*)task_packet;
m_navbuilder->save_all_tiles((char*)filename);
}
if(strcmp(task,"build all tiles")==0)
{
m_navbuilder->build_all_tiles();
}
if(strcmp(task,"add single tile")==0)
{
VECTOR* pos=(VECTOR*)task_packet;
m_navbuilder->build_tile(pos);
}
if(strcmp(task,"build tiles in bounds")==0)
{
VECTOR* min=(VECTOR*)task_packet;
VECTOR* max=(VECTOR*)second_task_packet;
m_navbuilder->build_tiles_box(min,max);
}
}
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//************************************
// BUILD A NAVMESH
//
DLLFUNC void* nav_build(custombuild* build_settings)
{
thread_function *thread_func=new thread_function(thread_dispatcher,"build the navmesh",(custombuild*)build_settings,(int*)NULL);
if(thread_func->is_alive()) return (thread_function *) thread_func;
delete thread_func;
return NULL;
}
you can easily convert to the type you need like
void bla(char* type ,void* arg1,void* arg2,void* arg3)
{
if(str_cmp(type,"a string"))
{
STRING* this_string=(STRING*)arg1;
if(this_string)
{
...
}
}
if(str_cmp(type,"an integer"))
{
int* this_integer=(int*)arg1;
if(this_integer)
{
...
}
}
if(str_cmp(type,"an integer with size"))
{
int* this_integer=(int*)arg1;
int* this_size=(int*)arg2;
if(this_integer && this_size>-1)
{
...
}
}
}
bla("a string",(STRING*)mystring,(int*)NULL,(int*)NULL);
//or
bla("a string",(STRING*)mystring,NULL,NULL);
bla("an integer",(int*)myinteger,......
bla("an integer with size",(int*)myinteger,(int*)my_size,NULL);
edit ah wait sid is on it
Last edited by Wjbender; 05/06/15 14:56.
Compulsive compiler
|
|
|
Re: function overloading problems (not working sometimes)
[Re: WretchedSid]
#451442
05/06/15 15:07
05/06/15 15:07
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
Speaking of though, not wanting to rain into your parade and I know you put some good effort into your array tools... But. What about something that is a tad more user friendly and also provides bounds checking? I mean absolutely no offense and I'll take the code down if you want to, but here is what I mean:
typedef struct
{
void *_buffer; // Actual data
size_t _size; // Number of elements
size_t _capacity; // Allocated number of elements
size_t _elementSize; // Element size
} array_t;
array_t *array_create(size_t elementSize)
{
array_t *array = malloc(sizeof(array_t));
array->_elementSize = elementSize;
array->_size = 0;
array->_capacity = 5; // start out with 5 elements. Tweak if desired. This just makes the life easier since there is always a buffer and we don't have to care about cases where it's NULL
array->_buffer = malloc(array->_capacity * array->_elementSize);
return array;
}
void array_delete(array_t *array)
{
free(array->_buffer);
free(array);
}
void __array_assert_size(array_t *array, size_t required) // Makes sure that the array fits
{
size_t toCopy = array->_size;
if(toCopy > size)
toCopy = size;
if(required > array->_capacity)
{
size_t nextCapacity = array->_capacity * 1.5; // Gives a nice grow curve. Alternatively doubling also works, gets messy with large arrays though
if(nextCapacity < required)
nextCapacity = required;
void *buffer = malloc(nextCapacity * array->_elementSize); // TODO: Handle errors
memcpy(buffer, array->_buffer, toCopy * array->_elementSize);
free(array->_buffer);
array->_buffer = buffer;
array->_capacity = nextCapacity;
}
else
{
size_t nextCapacity = array->_capacity >> 1;
if(nextCapacity >= required && nextCapacity > 5) // Keep at least space for 5 elements
{
void *buffer = malloc(nextCapacity * array->_elementSize); // TODO: Handle errors
memcpy(buffer, array->_buffer, toCopy * array->_elementSize);
free(array->_buffer);
array->_buffer = buffer;
array->_capacity = nextCapacity;
}
}
}
void array_copyin_data(array_t *array, void *data, size_t elements)
{
__array_assert_size(array, array->_size + elements);
memcpy(((char *)array->_buffer) + array->_size * array->_elementSize, data, elements * array->_elementSize);
array->_size += elements;
}
void array_copyout_data(array_t *array, void *data, size_t start, size_t elements)
{
if(start + elements >= array->_size)
{
printf("Trying to access elements [%d, %d) in array with only %d elements", start, start + elements, array->_size);
return;
}
memcpy((data, (char *)array->_buffer) + start * array->_elementSize, elements * array->_elementSize);
}
// Alternatively, you can also work with single elements at a time... Something like this:
void array_add_object(array_t *array, void *object)
{
__array_assert_size(array, array->_size + 1);
memcpy(((char *)array->_buffer) + array->_size * array->_elementSize, data, array->_elementSize);
array->_size ++;
}
I'll leave implementing other operations as exercise for anyone who wants to use something like this. It's merely to show the general idea anyway. Also, whipped up in like 10 minutes and didn't test it, so there might be syntax errors. I tried putting down some comments to make clear what the intend is. Edit: Fixed errernous usage of _size vs. _capacity. Edit 2: More edits
Last edited by WretchedSid; 05/06/15 17:31.
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
|