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

Generic programming in C

Name: Anonymous 2012-01-12 3:49

I love C so much, and I really want to hate sepples, but I can't help but think that generic programming in C is shit! Macros are no good for generic data structures, as they are clunky and blow out code size, nor are void pointers, as you need to allocate separate memory just to store an integer (don't stuff ints into pointers; zeros won't work on architectures where the null pointer constant is non-zero). I really want to write my data structure library in sepples, where templates allow type genericism without issue. What should I do, /prague/; what should I do?!

Name: /prog/ police !1fOeGamQwA!PrM413+Y2UUOlKE 2012-01-12 12:52

>>40
Go back to /g/.

Name: Anonymous 2012-01-12 13:40

#ifndef GENERIC_VECTOR_H__
#define GENERIC_VECTOR_H__

#define _LStruct(TYPE)                                                    \
struct {                                                                \
    int cap, num;                                                        \
    TYPE *table;                                                        \
}
#define DEF_LIST(NAME, TYPE)                                            \
typedef _LStruct(TYPE) NAME;                                            \
NAME NAME##Create() {                                                    \
    return (NAME){128, 0, malloc(128 * sizeof(TYPE))};                    \
}                                                                        \
void NAME##Push(NAME *v, TYPE t) {                                        \
    if(v->cap == v->num)                                                \
        v->table = realloc(v->table, (v->cap *= 2) * sizeof(TYPE));        \
    v->table[v->num++ % v->cap] = t;                                    \
}                                                                        \
TYPE NAME##Pop(NAME *v) {                                                \
    TYPE t = v->table[0];                                                \
    for(int i = 0; i < v->num - 1; i++) v->table[i] = v->table[i+1];    \
    return t;                                                            \
}

#endif


#include <stdio.h>
#include <stdlib.h>
#include "glist.h"
DEF_LIST(IntVec, int);

int main() {
    IntVec x = IntVecCreate();
    for(int i = 0; i < 3; i++) IntVecPush(&x, i);
    for(int i = 0; i < 3; i++) printf("%d ", IntVecPop(&x));
    printf("\n");
}


> 0 1 2

Name: Anonymous 2012-01-12 13:42

>>42
Fucking shitchan.

#ifndef GENERIC_VECTOR_H__
#define GENERIC_VECTOR_H__

#define _LStruct(TYPE)                                                  \
struct {                                                                \
    int cap, num;                                                       \
    TYPE *table;                                                        \
}
#define DEF_LIST(NAME, TYPE)                                            \
typedef _LStruct(TYPE) NAME;                                            \
NAME NAME##Create() {                                                   \
    return (NAME){128, 0, malloc(128 * sizeof(TYPE))};                  \
}                                                                       \
void NAME##Push(NAME *v, TYPE t) {                                      \
    if(v->cap == v->num)                                                \
        v->table = realloc(v->table, (v->cap *= 2) * sizeof(TYPE));     \
    v->table[v->num++ % v->cap] = t;                                    \
}                                                                       \
TYPE NAME##Pop(NAME *v) {                                               \
    TYPE t = v->table[0];                                               \
    for(int i = 0; i < v->num - 1; i++) v->table[i] = v->table[i+1];    \
    return t;                                                           \
}

#endif

Name: Anonymous 2012-01-12 13:51

>>42,43
Er, remove the % v->cap, was for a different circular buffer impl.

Name: Anonymous 2012-01-12 14:00

>>40
There is no function call stack in C you dumb Jew, there is no stack at all in C. Now fuck off you back to /g/ you piece of shit retard.

Name: Anonymous 2012-01-12 14:15

>>45
>2011
>being anal about stacks even though you very well know what he means
Confirmed for Asperger

Name: Anonymous 2012-01-12 14:18

>>46
back to /g/, please

Name: Anonymous 2012-01-12 14:18

The oroginal source for CFront:


/* CFront.h: The revolutional object system */

#ifndef orgasm_h_
#define orgasm_h_

#define class struct

#endif

Name: Anonymous 2012-01-12 14:18

>>47
back to /b/, please

Name: Anonymous 2012-01-12 14:21

>>46
I really don't know what he means, please explain it to me.

Name: Anonymous 2012-01-12 14:22

>>50
Go back to /g/

Name: Anonymous 2012-01-12 14:28

using C instead of cobol

Name: Anonymous 2012-01-12 14:31

>>51
No, please explain to me what he means when he's talking about a stack in C, please do, because I can't find it mentioned anywhere in C89, C99 or C11.

Name: Anonymous 2012-01-12 14:35

>>3,40,46
The C standard does not describe or mention a "stack." In many implementations, the activation record, arguments, and local variables are stored in different regions of memory or registers. The System/360 (S/370, S/390, and System z) uses a linked list of activation records allocated using GETMAIN and separate memory regions for the argument list and local variables, also allocated using GETMAIN. Similarly, the ARM allows "chunked stacks" where each activation record is part of a linked list. The VAX uses a contiguous stack for return addresses, but also has CALLG which is a standard call where the argument list can be anywhere in memory. Many RISCs pass arguments in registers and store the return address in a register, so they are able to complete a function call without even touching a stack. Other machines may use separate stacks for return addresses, arguments, and local variables, and may further break them down depending on whether these items are integers, floating-point, or pointers. Some small architectures like PICs may use static variables for all functions that are determined at compile time not to be recursive, allowing the fixed-size stack to be conserved for storing return addresses without violating the standard.

Name: Anonymous 2012-01-12 15:04

>>40
C is a high level language, it has no notion or knowledge of a call stack.

Name: Anonymous 2012-01-12 15:23

>>54
Many RISCs pass arguments in registers and store the return address in a register, so they are able to complete a function call without even touching a stack.
Don't forget Itanium, it does (did?) all that and more.

Some small architectures like PICs may use static variables for all functions that are determined at compile time not to be recursive, allowing the fixed-size stack to be conserved for storing return addresses without violating the standard.
That's not really about an architecture, only about compiler. Keil Microvision did that for 8051, but seamlessly switched to compiling functions as reentrant (all locals on stack) if necessary. I sometimes wonder why none of the major x86 compilers do that, if you don't count inlining as the logical conclusion of this approach.

Name: Anonymous 2012-01-12 22:31

>>48

But a class isn't a struct. It's a struct that defaults members to be private. And C++ structs are better than C structs. They have an implicit typedef and can have methods as well as member variables.

Why shouldn't one just use C++ instead of tossing around shitty C hacks?

Name: Anonymous 2012-01-12 22:35

>>53
I'm sorry I can't hear you over my awesome C implementation

Name: Anonymous 2012-01-12 22:43

If you are still here OP I'd be interested in your thoughts on the technique in >>42 considering it does not duplicate code for every use of the data structure.

Name: Anonymous 2012-01-12 22:55

>>58
3/10

Name: Anonymous 2012-01-12 22:57

>>60
You're just mad because you have an inferior implementation on a toy architecture. ;)

Name: Anonymous 2012-01-13 0:12

>>57
Did you read this thread at all? C++ started out as a c pre- OH, you're a troll. Good one, I almost got mad

Name: Anonymous 2012-01-13 1:36

Simple solution to all of this bumfuckery:




































































USE LISP!

Name: Anonymous 2012-01-13 2:04

(Post truncated.) is an inherently sinful message.

End the delusions. Open your chakras.

Name: Anonymous 2012-01-13 3:20

>>59
Still a disgusting abuse of preprocessor macros. It's hardly elegant.

Name: Anonymous 2012-01-13 5:57

>>59
Well I'm not OP but _LStruct is a reserved identifier, you managed to make it O(n) even though you're only defining two operations on it which you named push and pop and are commonly used for stacks, you never check malloc or realloc for failing so it will probably just segfault after a while considering you're just allocating double the amount of memory every time and  you never give any option to create it a capacity of less than 128 elements.

Name: Anonymous 2012-01-13 14:21

>>66
You are an idiot. It's a proof of concept, and you didn't bring a single conceptual issue to bare. Why don't you go and argue about the color of some bike sheds?

Name: Anonymous 2012-01-13 17:00

>>45,50,53,54
call stack semantics you nerds

Name: Anonymous 2012-01-13 17:13

The real solution to all the world's problems lies somewhere between void* and C++.

Name: Anonymous 2012-01-13 17:23

>>67
It's a pretty bad proof of concept.

Name: Anonymous 2012-01-13 19:18

>>67
Well I'm sorry that you're a fucking retard, and if you really want to know, the concept is fucking retarded as well.

Name: Anonymous 2012-01-13 19:25

>>71
/polecat kebabs/

Name: Anonymous 2012-01-13 21:15

C11 has improved generic support for the preprocessor.

Check out GCC 4.7 or Clang 3.1 nightly snapshots.

Name: Anonymous 2012-01-13 21:44

>>73
What is your point? You have to know all the types you want to generate functions for before you create the generic selection macro so it does nothing to aid us in this situation.

Name: Anonymous 2012-01-13 22:16

>>40
Actually, I guess what >>39-san is saying is that nowhere in the standard that defines C there is any mention of a "function call stack". It is usually implemented that way but that is not mandatory. Officially, C does not have a stack.

In fact, in some architectures, it is not even an advantage for it to be implemented with them.

Name: Anonymous 2012-01-14 3:18

>>1
architectures where the null pointer constant is non-zero

are retarded and don't deserve support.

Name: Anonymous 2012-01-14 3:21

>>76
Support my anus

Name: Anonymous 2012-01-14 3:22

>>77
gladly

Name: Anonymous 2012-01-14 5:16

>>76
I don't want to write a program in C that makes assumptions about the target hardware that aren't necessarily true.

Name: Anonymous 2012-01-14 5:29

>>79
If you compare the logical value of pointers to a constant integer zero, you should be fine. But if you use memcmp or do union or casting tricks to compare the bit pattern of the pointer to the bit pattern of an integer with a value of zero, it is not guaranteed to be zero.
#include <assert.h>
int main(void) {
     union {
          void *p;
          int i;
     } u;
     u.p = 0;
     void *p = 0;
     int i = 0;
     assert(p == u.p); /* true */
     assert(p == 0); /* true */
     assert(u.p == 0); /* true */
     //assert((int)p == i); /* not guaranteed */
     //assert((int)u.p == u.i); /* not guaranteed */
     //assert(p == (void *)i); /* not guaranteed */
     //assert(u.p == (void *)u.i); /* not guaranteed */
     //assert(memcmp(&u.i, &i, sizeof(int)); /* not guaranteed */
}

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