在编译时初始化数据 [英] initializing data at compile time

查看:66
本文介绍了在编译时初始化数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我有一个关于如何将冗余信息放入数据的问题

结构,在编译时初始化。由于性能原因,这通常是必要的

,并且不能在运行时完成(数据

结构是只读的)

理想情况下一个应该能够自动存储冗余的

信息,这样就不会出错。但是很多情况下我认为没办法这样做。


愚蠢而简单的例子:

typedef unsigned char u8;

const char lbl0 [3] =" cow" ;;

const char lbl1 [5] =" horse";

struct _header

{

const char * label;

u8长度;

};

#define fill_header(lbl){(lbl),sizeof(lbl)}

const struct _header headers [] =

{

fill_header(lbl0),

fill_header(lbl1)

};


struct _vector

{

const int * data;

u8 header; //索引到标题结构

u8 headerlength; //标题长度字段的副本

};


extern const int p0 [3];

extern const int p1 [4];


#define USEHEADER(h)(h),header [(h)]。length

const struct _vector vectorA [] =

{

{p0,USEHEADER(0)},//使用标签牛

{p1,USEHEADER(1)}, //标签马用于

};

const struct _vector vectorB [] =

{

{p0 ,0,3},//使用标签牛

{p1,1,5},//使用标签马

};


首先我用字符串+长度(标题)定义一个数组。接下来我

定义一个数组,其中包含引用这些字符串的数据。每个元素

该数组都包含一个索引到标题,还有一些冗余的

信息,我不能经常使用自动方法。 vectorA没有

编译。所以我必须手动将它(vectorB)放在那里,当然这对于大数据结构来说很容易出错并且很容易出现笨拙。有没有人现在用C语言自动化这样的优雅

方法?或者我是否必须使用其他方法生成

数据结构? (例如perl)当我尝试在

编译时对相关结构进行一些完整性检查时,我有相同类型的

问题。


问候,

Bart Goeman

Hi,

I have a question about how to put redundant information in data
structures, initialized at compile time. This is often necessary
for performance reasons and can''t be done at run time (data
structures are read only)
Ideally one should be able to put the redundant
information there automatically so no mistakes are possible, but in a lot
of case I see no way how to do it.

stupid but simple example:
typedef unsigned char u8;
const char lbl0[3] = "cow";
const char lbl1[5] = "horse";
struct _header
{
const char * label;
u8 length;
};
#define fill_header(lbl) {(lbl),sizeof(lbl)}
const struct _header headers[]=
{
fill_header(lbl0),
fill_header(lbl1)
};

struct _vector
{
const int * data;
u8 header; //index into headers structure
u8 headerlength; //copy of the length field of the header
};

extern const int p0[3];
extern const int p1[4];

#define USEHEADER(h) (h), headers[(h)].length
const struct _vector vectorA[]=
{
{p0,USEHEADER(0)}, //label cow is used
{p1,USEHEADER(1)}, //label horse is used
};
const struct _vector vectorB[]=
{
{p0,0,3}, //label cow is used
{p1,1,5}, //label horse is used
};

First I define an array with strings + the length (headers). Next I
define an array with data that references these strings. Each element of
the array holds an index into the headers, and also some redundant
information, the length of the header string. To initialize the redundant
information, I can''t often use an automated method. vectorA does not
compile. So i have to put it there manually (vectorB), which is of course
error-prone and clumsy for big data structures. Does anyone now an elegant
method to automate things like this in C? Or do I have to generate the
data structures using other means? (e.g. perl) I have the same type of
problems when I try to do some sanity checks on related structures at
compile time.

regards,
Bart Goeman

推荐答案

2004年12月18日星期六20:48:59 GMT, Bart Goeman< bg*@pandora.be>在comp.lang.c中写了


On Sat, 18 Dec 2004 20:48:59 GMT, Bart Goeman <bg*@pandora.be> wrote
in comp.lang.c:


我有一个关于如何在数据中放入冗余信息的问题


冗余信息是什么意思?为什么你认为你需要它?
结构,在编译时初始化。由于性能原因这通常是必要的,并且不能在运行时完成(数据结构是只读的)
理想情况下应该能够提供冗余的信息自动,所以没有错误是可能的,但在很多情况下,我认为没办法怎么做。

愚蠢而简单的例子:
typedef unsigned char u8;
const char lbl0 [3] =" cow";
const char lbl1 [5] =" horse" ;;


你意识到上面的数组不是字符串,因为它们缺少

终止''\ 0''。任何将它们传递给C字符串处理

函数都会产生不确定的行为。

struct _header


不要这样做,为什么你认为你需要用

下划线开始一个标签名称?所有以下划线开头的标识符都保留

,在普通和标记名称

空格的文件范围内实现。

{
const char * label;
u8 length;
};
#define fill_header(lbl){(lbl),sizeof(lbl)}
const struct _header headers [] =
{
fill_header(lbl0),
fill_header(lbl1)
};

struct _vector
{
const int *数据;
u8标题; //索引到头部结构中
u8 headerlength; //标题长度字段的副本
};

extern const int p0 [3];
extern const int p1 [4];

#define USEHEADER(h)(h),header [(h)]。length
const struct _vector vectorA [] =
{
{p0,USEHEADER(0)},/ /标签牛用于
{p1,USEHEADER(1)},//标签马用于
};


当然这不起作用。您正在尝试初始化一个成员

的结构,其静态存储持续时间的值为

对象。这不是编译时常量表达式,因此不是有效的


const struct _vector vectorB [] =
{
{p0, 0,3},//使用标签牛
{p1,1,5},//使用标签马
};


这里真正的问题是你的中间结构。你为什么需要

呢?它包含的是一个指向char的指针和数组的长度

的字符,无论如何你将数组的长度放入更高的

级别结构中。为什么不消除中间的

结构并将char指针和长度直接放在最终的

数组中?


其他替代方案是省略冗余。尺寸参数来自

最终结构。你为什么需要两次?

冗余是什么意思?为什么你认为它在稳健性方面会给你带来好处?

首先我用字符串+长度(标题)定义一个数组。接下来我定义一个包含引用这些字符串的数据的数组。数组的每个元素都包含一个标题索引,还有一些冗余的信息,标题字符串的长度。要初始化冗余的信息,我不能经常使用自动方法。 vectorA没有编译。所以我必须手动将它(vectorB)放在那里,这对于大数据结构来说当然容易出错并且很笨拙。现在有没有人用C语言自动化这样的优雅方法?或者我是否必须使用其他方法生成
数据结构? (例如perl)当我在编译时尝试对相关结构进行一些完整性检查时,我遇到了相同类型的问题。

问候,
Bart Goeman
Hi,

I have a question about how to put redundant information in data
What do you mean by "redundant information"? Why do you think you
need it?
structures, initialized at compile time. This is often necessary
for performance reasons and can''t be done at run time (data
structures are read only)
Ideally one should be able to put the redundant
information there automatically so no mistakes are possible, but in a lot
of case I see no way how to do it.

stupid but simple example:
typedef unsigned char u8;
const char lbl0[3] = "cow";
const char lbl1[5] = "horse";
You realize that the arrays above are not strings, as they are missing
the terminating ''\0''. Any passing of them to C string handling
functions produces undefined behavior.
struct _header
Don''t do this, why do you think you need to start a tag name with an
underscore? All identifiers beginning with an underscore are reserved
by the implementation at file scope in both the ordinary and tag name
spaces.
{
const char * label;
u8 length;
};
#define fill_header(lbl) {(lbl),sizeof(lbl)}
const struct _header headers[]=
{
fill_header(lbl0),
fill_header(lbl1)
};

struct _vector
{
const int * data;
u8 header; //index into headers structure
u8 headerlength; //copy of the length field of the header
};

extern const int p0[3];
extern const int p1[4];

#define USEHEADER(h) (h), headers[(h)].length
const struct _vector vectorA[]=
{
{p0,USEHEADER(0)}, //label cow is used
{p1,USEHEADER(1)}, //label horse is used
};
Of course this does not work. Your are trying to initialize a member
of structures with static storage duration with the value of an
object. This is not a compile time constant expression, and so is not
valid.
const struct _vector vectorB[]=
{
{p0,0,3}, //label cow is used
{p1,1,5}, //label horse is used
};
The real problem here is your intermediate structure. Why do you need
it? All it contains is a pointer to char and the length of the array
of chars, and you are putting the length of the array into the higher
level structure anyway. Why not just eliminate the intermediate
structure and put the char pointer and length directly in the final
array?

The other alternative is to omit the "redundant" size parameter from
the final structure. Why do you need it twice? What is the point of
the redundancy? Why do you think it buys you in terms of robustness?
First I define an array with strings + the length (headers). Next I
define an array with data that references these strings. Each element of
the array holds an index into the headers, and also some redundant
information, the length of the header string. To initialize the redundant
information, I can''t often use an automated method. vectorA does not
compile. So i have to put it there manually (vectorB), which is of course
error-prone and clumsy for big data structures. Does anyone now an elegant
method to automate things like this in C? Or do I have to generate the
data structures using other means? (e.g. perl) I have the same type of
problems when I try to do some sanity checks on related structures at
compile time.

regards,
Bart Goeman




你仍然没有解释是否需要冗余信息。

我不能想到在程序中对此有任何特殊需求。


如果你有一个特定的问题,你试图解决,或者你想要收到的特定的

结果,如果你再次发布

并解释你实际上想要实现的目标会更好。

那么也许我们可以提出一个更好的方法来解决它。


-

Jack Klein

http://JK-Technology.Com

常见问题解答

comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html

comp.lang.c ++ http://www.parashift.com/c++-faq-lite/

alt。 comp.lang.learn.c-c ++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html



You still haven''t explained the need for the "redundant" information.
I can''t think of any particular need for this in a program.

If you have a specific problem you are trying to solve, or a specific
result you are trying to receive, it would be better if you posted
again and explained what it is you are actually trying to accomplish.
Then perhaps we can suggest a better way to go about it.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html


Op Sat,2004年12月18日16:32:06 -0600,schreef Jack Klein:
Op Sat, 18 Dec 2004 16:32:06 -0600, schreef Jack Klein:
2004年12月18日星期六20:48:59 GMT,Bart Goeman< bg * @ pandora.be>在comp.lang.c中写道

On Sat, 18 Dec 2004 20:48:59 GMT, Bart Goeman <bg*@pandora.be> wrote
in comp.lang.c:


我有一个关于如何将冗余信息放入数据的问题
冗余信息是什么意思?为什么你认为你需要它?
Hi,

I have a question about how to put redundant information in data
What do you mean by "redundant information"? Why do you think you
need it?
结构,在编译时初始化。由于性能原因这通常是必要的,并且不能在运行时完成(数据结构是只读的)
理想情况下应该能够提供冗余的信息自动,所以没有错误是可能的,但在很多情况下,我认为没办法怎么做。

愚蠢而简单的例子:
typedef unsigned char u8;
const char lbl0 [3] =" cow";
const char lbl1 [5] =" horse";
structures, initialized at compile time. This is often necessary
for performance reasons and can''t be done at run time (data
structures are read only)
Ideally one should be able to put the redundant
information there automatically so no mistakes are possible, but in a lot
of case I see no way how to do it.

stupid but simple example:
typedef unsigned char u8;
const char lbl0[3] = "cow";
const char lbl1[5] = "horse";



你意识到上面的数组是不是字符串,因为它们缺少
终止''\0''。任何将它们传递给C字符串处理函数都会产生不确定的行为。



You realize that the arrays above are not strings, as they are missing
the terminating ''\0''. Any passing of them to C string handling
functions produces undefined behavior.




我知道。这是一个简单的例子。

它节省了一些空间,而pascal类型的字符串在我的应用程序中更加美观,因为我必须通过串行线检索它们,如果您知道需要请求多少字节,那么它就更容易了。但是关闭了

点。



yes i know. it''s a simple example.
it saves some space however, and pascal type strings hare more handsome in
my application since I have to retrieve them over a serial line, it''s
easier if you know before how many bytes you need to request. but is off
the point.

struct _header
struct _header



不要这样做,为什么你认为你需要用
下划线开始标记名称?所有以下划线开头的标识符都由普通和标记名称
空间中的文件范围内的实现保留。



Don''t do this, why do you think you need to start a tag name with an
underscore? All identifiers beginning with an underscore are reserved
by the implementation at file scope in both the ordinary and tag name
spaces.



你有一个观点。糟糕的做法。


You have a point. Bad practice.

{
const char * label;
u8长度;
};
#define fill_header(lbl){(lbl),sizeof(lbl)}
const struct _header headers [] =
{
fill_header(lbl0),
fill_header(lbl1)
};

struct _vector
{
const int * data;
u8 header; //索引到头部结构中
u8 headerlength; //标题长度字段的副本
};

extern const int p0 [3];
extern const int p1 [4];

#define USEHEADER(h)(h),header [(h)]。length
const struct _vector vectorA [] =
{
{p0,USEHEADER(0)},/ /标签牛用于
{p1,USEHEADER(1)},//使用标签马
};
{
const char * label;
u8 length;
};
#define fill_header(lbl) {(lbl),sizeof(lbl)}
const struct _header headers[]=
{
fill_header(lbl0),
fill_header(lbl1)
};

struct _vector
{
const int * data;
u8 header; //index into headers structure
u8 headerlength; //copy of the length field of the header
};

extern const int p0[3];
extern const int p1[4];

#define USEHEADER(h) (h), headers[(h)].length
const struct _vector vectorA[]=
{
{p0,USEHEADER(0)}, //label cow is used
{p1,USEHEADER(1)}, //label horse is used
};



当然这不起作用。您正在尝试使用
对象的值初始化具有静态存储持续时间的结构成员。这不是编译时常量表达式,因此不是有效的。



Of course this does not work. Your are trying to initialize a member
of structures with static storage duration with the value of an
object. This is not a compile time constant expression, and so is not
valid.




这是我的问题的核心。在C中,headers [h] .length不是一个编译时常量表达式,但每个理智的人都会说它真的是

是一个编译时常量表达式,因为header是一个const

数组。所以我要问有没有办法绕过这个C限制?



this is the core of my question. in C, headers[h].length is not a
compile-time constant expression, but every sane person will say it really
is a compile-time constant expression, since headers is a const
array. So I''m asking is there any way to circumvent this C limitation?

const struct _vector vectorB [] =
{
{p0,0,3},//使用标签牛
{p1,1,5},//使用标签马
};
const struct _vector vectorB[]=
{
{p0,0,3}, //label cow is used
{p1,1,5}, //label horse is used
};


字符数组长度的指针,无论如何,您将数组的长度放入更高级别的结构中。为什么不直接消除中间结构并将char指针和长度直接放在最终数组中?

另一种选择是省略冗余数据。来自
最终结构的尺寸参数。你为什么需要两次?
冗余有什么意义?为什么你认为它在稳健性方面会给你带来好处?



The real problem here is your intermediate structure. Why do you need
it? All it contains is a pointer to char and the length of the array of
chars, and you are putting the length of the array into the higher level
structure anyway. Why not just eliminate the intermediate structure and
put the char pointer and length directly in the final array?

The other alternative is to omit the "redundant" size parameter from the
final structure. Why do you need it twice? What is the point of the
redundancy? Why do you think it buys you in terms of robustness?

首先我用字符串+长度(标题)定义一个数组。接下来我定义一个包含引用这些字符串的数据的数组。数组的每个元素都包含一个索引到标题中,还有一些冗余的信息,即标题字符串的长度。要初始化
冗余信息,我不能经常使用自动方法。 vectorA
无法编译。所以我必须手动将它(vectorB)放在那里,这对于大数据结构来说当然容易出错且笨拙。现在有人在C中自动执行这样的事情是一种优雅的方法吗?或者我是否必须使用其他方法生成数据结构? (例如perl)当我在编译时尝试对
相关结构进行一些健全性检查时,我有同样类型的问题。

问候,
Bart Goeman
First I define an array with strings + the length (headers). Next I
define an array with data that references these strings. Each element
of the array holds an index into the headers, and also some redundant
information, the length of the header string. To initialize the
redundant information, I can''t often use an automated method. vectorA
does not compile. So i have to put it there manually (vectorB), which
is of course error-prone and clumsy for big data structures. Does
anyone now an elegant method to automate things like this in C? Or do I
have to generate the data structures using other means? (e.g. perl) I
have the same type of problems when I try to do some sanity checks on
related structures at compile time.

regards,
Bart Goeman



你仍然没有解释冗余的必要性。信息。我不能想到在程序中对此有任何特殊需求。

如果你有一个特定的问题,你试图解决,或者特定的结果你是试图接收,如果你再次发布会更好
并解释你实际上想要完成的是什么。然后
或许我们可以建议一个更好的方法来解决它。



You still haven''t explained the need for the "redundant" information. I
can''t think of any particular need for this in a program.

If you have a specific problem you are trying to solve, or a specific
result you are trying to receive, it would be better if you posted again
and explained what it is you are actually trying to accomplish. Then
perhaps we can suggest a better way to go about it.




我想给一个简单的&

短例如,但显然我的例子太简单了。


通常需要冗余信息来加速计算。对于嵌入式应用程序而言,速度比桌面应用程序更加严重。

它在稳健性方面绝对没有购买,当然,它更糟糕,
但是应该可以通过编译器/预处理器构造值来避免健壮性问题。


这个冗余信息可以是在程序开始时计算,

这是一个简单的解决方案,但对于内存很少RAM的嵌入式

应用程序来说,这是一个问题,你想将它存储在ROM / flash。

但C让生活变得困难。


我会给你2个真实世界的例子。事实上我知道更多的例子,

这是我经常遇到的问题。


示例1:

我有一个带LCD显示屏的设备。它可以显示消息

比例字体存储在ROM中;一个const数组用于

每个ascii字符的字符宽度,一些其他信息和指向实际位图的
指针。其次,你有另一个大的const数组

,里面有很多固定的消息。如果消息不适合

屏幕(77列),则必须在显示时滚动它,因此您需要

来了解每条消息的宽度。为了加快你想要的程序,你需要b $ b存储一条消息的宽度,这样你就可以立即知道你是否需要滚动浏览
。消息的宽度当然是多余的,你可以在运行时计算它的b $ b。但如果有很多ROM可用且时间不是这个

信息应该存储在ROM中


你知道这个在程序开始之前,

所以你想在邮件中存储宽度

array->必须是const->必须在编译时初始化



typedef unsigned char u8;

typedef unsigned简短的u16;


struct s_font

{

u8 width; //#columns

const u8 * pBitmap; //高度是固定的(16),所以2个字节/列

};


const struct s_font font [256] =

{

// fontdata

};


struct s_msg

{

const char * msg;

u16宽度;

};


const struct s_msg msg [] =

{

{" hello world",0},// width ??

{" Too many characters",0} ,//宽度??

{" bold",0},//宽度??

};



I wanted to give a simple &
short example, but apparently my example was far too simple.

Redundant information is often needed to speed up calculations. Speed is
far more an issue for embedded applications than for desktop apps.
It buys abolutely nothing in terms of robustness, it''s worse of course,
but it should be possible to avoid the robustness issue by constructing
the values by the compiler/preprocessor.

This redundant information can be calculated at the start of the program,
this is an easy solution, but it''s a problem for embedded
applications with few RAM available, you want to store it in ROM/flash.
but C makes life difficult.

I will give you 2 real-world examples. In fact I know far more examples,
it''s a problem I hit into quite often.

Example 1:
I have a device with a LCD display. It can display messages
A proportional font is stored in ROM; a const array with for
each ascii character the width of the character, some other info and a
pointer to the actual bitmap. Second, you have another big const array
with a lot of fixed messages in it. If the message does not fit on the
screen (77 columns) you have to scroll it when you display it, so you need
to know the width of each message. To speed up the program you want to
store the width of a message, so you know immediately if you have to
scroll. The width of the message is of course redundant, you can calculate
it at run-time. but if a lot of ROM is available and time is not this
information should be stored in ROM

You know this before the program starts,
so you want to store the width in the messages
array-> has to be const->has to be initialized
at compile time.

typedef unsigned char u8;
typedef unsigned short u16;

struct s_font
{
u8 width; //#columns
const u8 * pBitmap; //height is fixed(16), so 2 bytes/column
};

const struct s_font font[256]=
{
//fontdata
};

struct s_msg
{
const char * msg;
u16 width;
};

const struct s_msg msg[]=
{
{"hello world",0}, //width??
{"Too many characters",0}, //width??
{"bold",0}, //width??
};


您可以使用以下方法在Pas中存储pascal字符串:


typedef struct pString {

int len; //没有零的字符数

char * str;

} PSTRING;


PSTRING foo = {

sizeof(" myString") - 1,//避免计算尾随零

" myString"

};


或者你可以


#define MAKE_PSTRING(a){sizeof(a)-1,a}


然后


PSTRING foo = MAKE_PSTRING(" myString");
You can store pascal strings in C using:

typedef struct pString {
int len; // Number of chars without the zero
char *str;
} PSTRING;

PSTRING foo = {
sizeof("myString")-1, // Avoid counting the trailing zero
"myString"
};

or you can

#define MAKE_PSTRING(a) { sizeof(a)-1,a}

then

PSTRING foo = MAKE_PSTRING("myString");


这篇关于在编译时初始化数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆