, , UB - , test , .
() - , struct TLV .
, __attribute__((packed)).
, 100% UB.
, value , , , .
, sizeof(unsigned char) 1, . , malloc(n*sizeof(T)) T, n T. C , unsigned char , char ( ).
, assert(.), .
, , - , .
:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef struct {
unsigned char type;
unsigned char length;
unsigned char value;
} TLV;
static TLV dummy;
int main(void) {
assert(offsetof(TLV,value)==(sizeof(dummy.type)+sizeof(dummy.length)));
unsigned char test[5] = {(unsigned char)'T', 0x03, 0x01, 0x02, 0x03};
TLV* tlv=(TLV*)test;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",(&tlv->value)[i]);
}
(&tlv->value)[0]=253;
(&tlv->value)[1]=254;
(&tlv->value)[2]=255;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",(&tlv->value)[i]);
}
return EXIT_SUCCESS;
}
(C99 ) :
#include <stdlib.h>
#include <stdio.h>
typedef struct {
unsigned char type;
unsigned char length;
unsigned char value[];
} TLV;
int main(void) {
TLV* tlv=malloc(sizeof(TLV)+3*sizeof(unsigned char));
tlv->type='T';
tlv->length=3;
tlv->value[0]=1;
tlv->value[1]=2;
tlv->value[2]=3;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",tlv->value[i]);
}
tlv->value[0]=253;
tlv->value[1]=254;
tlv->value[2]=255;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",tlv->value[i]);
}
free(tlv);
return EXIT_SUCCESS;
}
, , (, , ) , , char .
() , , , , value ( - ), TLV. , , length size_t - "" .
The current length limit of 255 (on almost all platforms) is frankly mean. That was in 1993 at Turbo Pascal. In 2015, he jumps. At least, implement it lengthas an `unsigned int 'if you do not know that such a stretch ceiling is enough.