I would avoid the use of malloc to initialize a structure and I’m looking for the best practice for the design a C software using an oo-style (where possible).
Only C99, not C++
First question, what is preferable when use a struct like an object? typedef its pointer or not?
These are my test(all works using gcc compiler):
case 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct sItem{
int n;
char* text;
} oItem, *Item;
int main(int argc, char** argv) {
Item i1=(&(oItem){.n=1, .text="A"});
Item i2=(&(oItem){.n=100, .text="ABC"});
printf("%d, %s, %d\n", i1->n, i1->text, sizeof(*i1)); // 1, "A", 8
printf("%d, %s, %d\n", i2->n, i2->text, sizeof(*i2)); // 1, "ABC", 8
return (EXIT_SUCCESS);
}
This works, but i think it should not because text is not initialized to contains strings.
Is this an invalid piece of code?
case 2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct sItem{
int n;
char text[5];
} oItem, *Item;
int main(int argc, char** argv) {
Item i1=(&(oItem){.n=1, .text="A"});
Item i2=(&(oItem){.n=100, .text="ABC"});
printf("%d, %s, %d\n", i1->n, i1->text, sizeof(*i1)); // 1, "A", 12
printf("%d, %s, %d\n", i2->n, i2->text, sizeof(*i2)); // 1, "ABC", 12
return (EXIT_SUCCESS);
}
This works and I think it is correct, is it?
case 3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Item_new(i, n, s) (&(oItem){0});Item_ctor(i, n, s);
#define Item_neww(i, x, s) (&(oItem){\
.n=x,\
.text=s\
})
typedef struct sItem{
int n;
char text[5];
} oItem, *Item;
void Item_ctor(Item i, int n, char* text){
i->n=n;
strcpy(i->text, text);
}
int main(int argc, char** argv) {
Item i1=Item_new(i1, 10, "ABC");
Item i2=Item_neww(i2, 10, "ABC");
printf("%d, %s, %d\n", i1->n, i1->text, sizeof(*i1)); // 10, "ABC", 12
printf("%d, %s, %d\n", i2->n, i2->text, sizeof(*i2)); // 10, "ABC", 12
return (EXIT_SUCCESS);
}
I think this is very nice, but hides the code, and perhaps might be harmful, what do you think?
I case 3, what is the best choice: macro or constructor function?
Don’t do 3, macros that contain unprotected
;make me extremely nervous.Instead I would replace your “new” and “ctor” by the following
This doesn’t break the expectation of the user for
Item_new: a realfunction like macro that returns a value.
And the ctor should do the necessary checks and never overwrite the memory,
i->text[4]will always be0. (Better would be to have a symbolic constant instead of5and use it also for thestrncpycall.)