Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

Type agnosticism, data structures and C

Name: Anonymous 2011-09-16 6:07

/prog/, I've been working on a C library with basic data structures and useful functions, and have implemented things like doubly-linked lists and vectors and so on. Now I'm working on Unicode-based string support. Here's my issue.

I've implemented type agnosticism on the vector type using void pointers (not preprocessor macros), so I want to use the vector type to represent a string. Each Unicode codepoint is an int32_t. Of course, I don't want to have to allocate four bytes on the heap for each codepoint, then point to that from each vector element; that's utterly stupid. On the other hand, doing typecasts to shove an integer in the void * type is kludgy and works very poorly, often requiring double explicit casts; once to expand/shrink the type's size, then once more to explicitly cast to a pointer or back.

How can I solve my issues and use my vector type for strings?

Name: Anonymous 2011-09-16 6:10

Don't write in C.

Name: Anonymous 2011-09-16 6:14

>>2
You sure are helpful!

Name: Anonymous 2011-09-16 6:17

>>2
You sure are helpful!

Name: Anonymous 2011-09-16 6:18

>>2
You sure are helpful!

Name: Anonymous 2011-09-16 6:17

>>2
You sure are helpful!

Name: Anonymous 2011-09-16 6:32

/* The implementation is left as an exercise to the reader. */
typedef struct {
  size_t element_size;
  size_t allocated_space;
  size_t n;
  void* data;
} vector;

vector* make_vector(size_t element_size);
void delete_vector(vector* x);
void resize_vector(vector* x, size_t n);

Name: Anonymous 2011-09-16 6:35

>>7
Wouldn't that require a function call just to fetch/store values?

Name: Anonymous 2011-09-16 6:39

>>7
Also, that'd make using a vector for actual pointers a pain in the ass, and need casts all over the fucking place.

Name: Anonymous 2011-09-16 6:38

>>8
No. The reader knowns the real type of what is pointed by data and use it directly with casting.

Name: Anonymous 2011-09-16 6:40

>>10
My whole question revolves around finding a way to avoid excessive casting. Could you provide me with a relevant solution?

Name: Anonymous 2011-09-16 6:44

>>11
My solution is VALID ANSI C89 and one of the best. If the typecast really annoys you, you can #define VEC(x, type, i) (((type*) (x)->data)[i]).

Name: Anonymous 2011-09-16 6:46

>>12
Calling yourself the best doesn't provide credibility. Also, my entire library is valid ANSI C89, save for the requirement of C99's stdint.h, so your 'achievement' isn't all that extraordinary. Also, preprocessor macros are for faggots.

Name: Anonymous 2011-09-16 6:52

>>13
I did call my solution the best, not me.

Also, preprocessor macros are for faggots.
No, they aren't. That's what Bjarne Stroustrup wants you to believe.

If you absolutely want to avoid reader typecasting, the only solutions I see are:
- Switch to C++ and use templates;
- Implement dynamic typing, which will be slow as fuck;
- Use kludges such as the one you described in >>1.
Perhaps a better programmer will find others.

Name: Anonymous 2011-09-16 6:52

Also: what should be the default type for my generic data structures' payload?

- void *
- intmax_t
- uintmax_t
- intptr_t
- uintptr_t

Name: Anonymous 2011-09-16 6:54

OP here.

Switch to C++ and use templates;

Nope. This is a C library.

Implement dynamic typing, which will be slow as fuck;

Like glib's GObject? Ugh, that's exactly what I'm trying to avoid. This library is being written as a light and fast alternative to glib.

Use kludges such as the one you described in >>1.

Well, I am the OP, so...

Name: tdavis 2011-09-16 7:17

write your own compiler and improve on C/C++

Name: Anonymous 2011-09-16 7:21

>>16
Nope. This is a C library.
Then enjoy your AIDS.

I mean, it is fucking ridiculous, isn't it? You have found one of the cases that perfectly illustrate why C++ is hands down better than C. Or, rather, the case found you. Yet through a miracle of cognitive alchemy you manage to warp your vision of the situation to completely turn it inside-out, so that you can respond to the only possible sane advice with a quietly smug "this is a C library". Mind boggles.

Name: Anonymous 2011-09-16 7:28

>>18
I am >>14 and I disagree. Generic data structures are a sign of bad design or Greenspunning. The STL is a cancer.

Name: Anonymous 2011-09-16 7:52

http://azabani.com/git/index.cgi/generalist/plain/src/vector.h

/**
 * \file vector.h
 * This file defines a data structure for vectors (one-dimensional arrays), as
 * well as functions to manipulate them.
 */

#ifndef GENERALIST_VECTOR_H
#define GENERALIST_VECTOR_H

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

/**
 * The basic data structure for a vector.
 */

struct gvector_struct {

    /**
     * The pointer to the memory used for the vector. Integer values of the
     * same size and signedness as a void pointer can also be stored here,
     * but the void pointer data type varies between platforms, so this is not
     * good practice except under controlled, memory-tight conditions.
     */

    void **d;

    /**
     * The number of elements memory has been allocated for.
     */

    intmax_t a;

    /**
     * The number of elements currently stored.
     */

    intmax_t l;

};

/**
 * A vector should be passed around by a pointer to its structure.
 */

typedef struct gvector_struct *gvector;

/**
 * Allocate a new vector on the heap.
 * \return the new vector
 */

gvector gvector_alloc();

/**
 * Double the memory allocated to a vector.
 * \param v the vector
 * \return the vector
 */

void gvector_expand(gvector v);

/**
 * Add a new value to the end of a vector, with the data pointer provided.
 * \param v the vector
 * \param d the data pointer value
 */

void gvector_append(gvector v, void *d);

/**
 * Add a new value to the beginning of a vector, with the data pointer
 * provided.
 * \param v the vector
 * \param d the data pointer value
 */

void gvector_prepend(gvector v, void *d);

/**
 * Remove the first value of a vector, returning the removed value. If there
 * are no elements, return NULL.
 * \param v the vector
 * \return the data pointer, or NULL if there are no elements
 */

void *gvector_remove_first(gvector v);

/**
 * Remove the last value of a vector, returning the removed value. If there are
 * no elements, return NULL.
 * \param v the vector
 * \return the data pointer, or NULL if there are no elements
 */

void *gvector_remove_last(gvector v);

/**
 * Call a given function for each value, passing the value as the only argument
 * to the child function each time.
 * \param v the vector
 * \param f the function to be called for each value
 */

void gvector_each(gvector v, void (*f)(void *));

/**
 * Return the position index of the first element containing the given data
 * pointer as it is placed in the vector. If a value can not be found, return
 * -1.
 * \param v the vector
 * \param d the data pointer value
 * \return a non-negative position index if the value is found; -1 otherwise
 */

intmax_t gvector_index_value(gvector v, void *d);

/**
 * Return the position index of the first element in the vector that, when a
 * given comparator function is called with the value and the given data
 * pointer value as arguments, returns zero. If a value can not be found,
 * return -1.
 * \param v the vector
 * \param d the data pointer value
 * \param f the comparator function
 * \return a non-negative position index if the value is found; -1 otherwise
 */

intmax_t gvector_index_compare(gvector v, void *d, int (*f)(void *, void *));

/**
 * Reverses a vector in place.
 * \param v the vector
 */

void gvector_reverse(gvector v);

/**
 * Append one vector's contents to another vector.
 * \param v the vector to append to
 * \param w the vector to copy from
 */

void gvector_concat(gvector v, gvector w);

/**
 * Frees the memory used for a vector.
 * \param v the vector
 */

void gvector_destroy(gvector v);

#endif

Name: Anonymous 2011-09-16 7:53

That's vector.h as it is right now. The basic data type for each element is a void *, which should be the same size as a uintptr_t, I think.

Name: Anonymous 2011-09-16 8:03

>>19
Generic data structures are a sign of bad design or Greenspunning. The STL is a cancer.

Good lord look at all the autism in this post!

But let's try to be serious for a moment, assuming that is even possible with complete numbnuts like you around: At the implementation level, std::vector and std::map behave just exactly like containers in the GLib - the STL, however, provides proper reflection, making shit like vec_push_back(&crusty_cum, all_the_autism_in_this_thread, sizeof(crusty_cum)); unnecessary, because C++ is able to detect the size properly. Now go back to your hugbox, you grossly deformed LITHPu GNU/Blob, you.

Name: Anonymous 2011-09-16 8:11

>>22
But let's try to be serious for a moment, assuming that is even possible with complete numbnuts like you around: At the implementation level, std::vector and std::map behave just exactly like containers in the GLib
GLib is shit.

the STL, however, provides proper reflection, making shit like vec_push_back(&crusty_cum, all_the_autism_in_this_thread, sizeof(crusty_cum)); unnecessary, because C++ is able to detect the size properly.
The C Preprocessor, however, provides an overly-simplistic altough useful macro system, making shit like vec_push_back(&crusty_cum, all_the_autism_in_this_thread, sizeof(crusty_cum)); unnecessary, because it is trivial to use a macro to add the size parameter automatically.

Name: Anonymous 2011-09-16 8:20

>>23
macro

nigga doesn't know what reflection and RAII is!

Didn't I tell you to move your spongy ass back to your hugbox? What are you waiting for, retard? Join your kind at /g/.

Name: Anonymous 2011-09-16 8:23

>>24
As I showed in >>23, reflection isn't necessary in this case. And RAII hasn't got anything to do with the topic.
Also, my ass isn't spongy and I'm not a ni/g/ga.

Name: >>23 2011-09-16 8:28

>>22
Oh, by the way, that example was terribly bad, because there's no reason to pass the size as a parameter if it's already present in the vector structure.

Name: Anonymous 2011-09-16 9:46

>>24
ooc.lang.reflect

Name: Anonymous 2011-09-16 9:50

You should typedef a void * into something that you may change later at your convenience.

Name: Anonymous 2011-09-16 9:51

>>25
And RAII hasn't got anything to do with the topic.

laughing_whores.svg

Also, my ass isn't spongy and I'm not a ni/g/ga.

Keep telling that yourself, ``[i]brah[i]''.

Name: Anonymous 2011-09-16 9:52

>>14
Or just use clang which supports overloadable functions in C.

Name: Anonymous 2011-09-16 10:12

Why hello there mister OP.

If you would like to reliably store items of various sizes directly into your data structures without using pointers that point out to them, then I think you will have to use macros and compile your code with various appropriate definitions for the macros. If the data types just happens to be the same size, or smaller than a pointer, then you could probably get away with casting, but this wont be portable to architectures where the size of a pointer is smaller than the int. That probably wont happen though. Anyways, here is one way to get template like features out of C. I'll be using the ## preprocesser operator, which concatenates strings. I haven't tested this though.


vector.c

#include <malloc.h>
#include <assert.h>

// VECTOR and ITEM are defined elsewhere


struct VECTOR {
  ITEM* internal_array;
  int array_length;
};

ITEM get_##VECTOR (struct VECTOR* self, int index) {
  assert(index >= 0);
  assert(index < self->array_length);
  return self->internal_array[index];
}

...


vector.h


// ITEM is defined else where

#define VECTOR vector_##ITEM

VECTOR* new_##VECTOR(int initial_length);
ITEM get_##VECTOR(struct VECTOR* self, int index);

...


and then you can make c and h files for vectors of certain types:

vector_int.h

#ifndef __VECTOR_INT__
#define __VECTOR_INT__

#define TYPE int
#include "vector.h"

#endif


vector_int.c

#include "vector_int.h"
#include "vector.c"


vector_vp.h

#ifndef __VECTOR_VP__
#define __VECTOR_VP__

#define TYPE void*
#include "vector.h"

#endif


vector_vp.c

#include "vector_vp.h"
#include "vector.c"


I was going to do this a while ago, but I ended up just using C++.

Name: Anonymous 2011-09-16 10:16

>>31

sorry, I forgot to include an example of what it might look like to use this:

main.c

#include "vector_int.h"

int main(int argc, char** argv) {
  struct vector_int* test = new_vector_int(6);
  set_vector_int(test, 0, 1);
  printf("%d\n", get_vector_int(test, 0)); // prints 1
  free_vector_int(test)
  return 0;
}

Name: Anonymous 2011-09-16 10:51

>>31

If you would like to reliably store items of various sizes directly into your data structures without using pointers that point out to them, then I think you will have to use macros

correcting myself here. You could use unions as well, but this would force you to use more space than necessary when storing smaller types.

Name: FrozenVoid 2011-09-16 11:00

Why you need Unicode support? Can't you just learn English?

orbis terrarum delenda est

Name: tdavis 2011-09-16 11:14

LoseThos is supposed to be simple, though it's not extreme.  It's not intended to grow into a primary operating system.  It's for recreational programming.  In theory, you could ban running any 3rd party applications, but that'd suck.  Let the Chinese make their own -- it's only 130,000 LOC. 

If you balloon it, it will become "yuck".  It has fundamentals which are contrary to primary operating systems, but fine for what it is.

Who's to say what the right size is -- I imagien I'll keep working on it and it will become "yuck" and die.

Name: Anonymous 2011-09-16 11:45

Your library sucks. Slow as hell, you should allocate more from stack. One word, THE FORCED USAGE OF MALLOC THREAD OVER!!!

Name: Anonymous 2011-09-16 11:51

>>34
Why do you need to learn English? Can't you just learn Mandarin?

Name: Anonymous 2011-09-16 11:59

>>20
web design
No, I don't think you are experienced in web design. I think you know how to use html.

Name: FrozenVoid 2011-09-16 12:05

>>37
Mandarin requires more code support, more bytes for storage, and is far more restrictive in use of characters.
English can transcribe Mandarin perfectly, so there is no need to graphically represent it.




orbis terrarum delenda est

Name: Anonymous 2011-09-16 13:02

>>39
Why do you need to talk? Can't you just shut the fuck up?

Name: Anonymous 2011-09-16 18:04

>>40
Why are you replying to a troll?

Name: Anonymous 2011-09-16 18:35

>>41
Why are you replying to a troll?

Name: Anonymous 2011-09-16 21:11

>>39
Thank you for proving my point, Mandarin is obviously superior.

Name: n3n7i 2011-09-16 22:05


/**
     * The number of elements memory has been allocated for.
     */

    >> intmax_t a;

    /**
     * The number of elements currently stored.
     */

    >> intmax_t l;

Will store number of elements allocated / stored in every element of the vector?

Name: n3n7i 2011-09-16 22:25

maybe something like this?

typedef struct gvector_struct {
        void **d;
        };

struct arch_gvector{
        struct gvector_struct *gVect;
        intmax_t a;
        intmax_t l;
        };

struct arch_gvector ArchVect;

//ArchVect.a = No of stored elements
//ArchVect.l = No allocated
//ArchVect->gVect[i].d = element i

Name: root@eecs.berkeley.edu 2011-09-16 22:27

>>45
No. That totally sucks. Leave the programming to the legit engineers you fucking wanna be nigger.

Name: root@eecs.berkeley.edu 2011-09-16 22:30

>>44
Will store number of elements allocated / stored in every element of the vector?

Nothing is getting stored yet because the program never completed the translation unit. Once it does, the whole thing becomes a declaration. I would say go read the ANSI/ISO C standard, but I don't think you have the mental capacity for such terse reading.

Name: n3n7i 2011-09-16 22:53

...Unless you're doing something tricky with the **void?

...you probably could've explained it by now if you weren't groaning so much..

Name: n3n7i 2011-09-16 22:56

The only reason why I'm here on a friday night, instead of going out, is that I'm a total loser in real life. I'm also broke because I got fired from nambla.org

Name: n3n7i 2011-09-16 23:06

its saturday here.... =)

Name: n3n7i 2011-09-16 23:10

So, you could just malloc a *void to a vector..??

Name: Anonymous 2011-09-17 1:01

>>51 cretin

Name: Anonymous 2011-09-17 2:17

>>52
Please try to ignore troll posts. Modify this Greasemonkey program to filter out posts by the poster n3n7i.

http://userscripts.org/scripts/show/40415

Name: n3n7i 2011-09-17 3:17

>>44
Will store number of elements allocated / stored in every element of the vector?

>>47
Nothing is getting stored yet because the program never completed the translation unit. Once it does, the whole thing becomes a declaration.

...And then..?

Name: n3n7i 2011-09-17 3:27

you do something like >>51?

=) i thought your struct was the vector... nevermind though

Name: Anonymous 2011-09-17 8:28

You need an int24_t for storing Unicode.

...or just store it all in UTF-8.

Name: Anonymous 2011-09-17 9:39

>>56

>int24_t
I think you mean int32_t.

>store it all in UTF-8.
No fucking way I'll store it in UTF-8 in memory, requiring parsing and complex processing just to traverse the codepoints.

Name: n3n7i 2011-09-17 9:52

vector.

vector vector vector!

Have you tried replacing your code with vector?

VECTOR VECTOR ÜBER ALLES

everytime i masturbate i think of vector

vector i love you don't you see

my vector is better than your vector

Name: kodak_gallery_programmer !!NOuIr5+Z3dDMZ1a 2011-09-17 10:48

>>54

It becomes a tentative definition?

Don't change these.
Name: Email:
Entire Thread Thread List