存储管理实用程序包上的RFC [英] RFC on a storage management utility package

查看:48
本文介绍了存储管理实用程序包上的RFC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

长度道歉 - 这篇文章最好用固定字体查看

和行宽> = 72.


下面是源代码对于提供套件的C头文件

的存储管理宏。我正在征求意见。特别是

:有没有我忽略过的陷阱?

有任何改进建议吗?是否有一般的

可用优质套餐用相同的

一般许可做同样的事情?关于文档和建议的评论

用于改进它是受欢迎的。


当然,欢迎任何人使用这个小包装作为

他们认为合适。

/ * -------------------------------- --------------------------------- * /


/ *版权所有(c)2006年Richard Harter * /

/ * * /

/ *特此免费授予任何人* /

/ *获取此软件和相关文档的副本* /

/ *文件(软件),以便在没有* /
$ b $的情况下交易软件b / *限制,包括但不限于使用权,* /

/ *复制,修改,合并,发布,分发,再许可和/或* /

/ *出售本软件的副本,并允许向其提供* /

/ *软件的人员进行所以,受以下条件限制* /

/ *条件:* /

/ * * /

/ *上述版权声明及此条款许可声明应包含在* /

/ *软件的所有副本或实质部分中* /

/ *。 * /

/ * * /

/ *派生作品应包括软件为* /

/ *修改版的通知受版权保护的软件。 * /

/ * * /

/ *本软件按原样提供,不附带任何保证* /

/ *种类,明示或暗示,包括但不限于* /

/ *适销性保证,特定适用性* /

/ *目的和不侵权。在任何情况下,作者或* /

/ *版权所有者对任何索赔,损害或其他责任承担责任* /

/ *责任,无论合同是否在行动中,或者* /

/ *否则,由* /

/ *软件或软件中的使用或其他交易引起或与之相关。 * /

/ * * /

/ * -------------------------- --------------------------------------- * /

/ * * /

/ *这个包含文件提供了一套宏,简化了可分配存储的* /

/ *管理。有两组* /

/ *宏,分段空间宏和动态数组宏。 * /

/ *分段空间宏创建一系列段,其中* /

/ *段的类型都相同但大小可变。 * /

/ *动态数组宏创建一个可扩展的元素数组* /

/ *大小相同。通常,segspace宏用于* /

/ *创建原始类型的存储块,例如,int或* /

/ * chars;没有规定通过块索引。 * /

/ *另一方面,动态数组通常用于表格。 * /

/ * * /

/ *所有存储都是从堆中分配的。控制数据是* /

/ *全局到包含包含文件的文件。存储的所有引用* /

/ *应该是base + offset的形式(例如array * /

/ * indexing)而不是指针,因为基地址可以* /

/ *可以调整基数。调整大小总是向上,即* /

/ *存储元素的大小不会减小。每个单独的存储空间* /

/ *单位可以被不经意地释放。 * /

/ * * /

/ *用法:* /

/ * * /

/ *存储单元(分段空格或动态数组)应使用STF_DCL_SEGSPACE和* /

/ * STG_DCL_DYNARRAY宏在文件级声明* /

/ *。两个宏都使用类型和基数* /

/ * name作为参数;此外,STG_DCL_DYNARRAY宏具有* /

/ *包含数组长度的变量的地址。 * /

/ *名称 argument是包含* /

/ *变量的地址,该指针指向存储空间的base。 * /

/ * * /

/ *有两个用于增加segspace存储空间的宏,一个用于添加* /

/ *一个段和一个修剪最后一段的长度。 * /

/ * STG_ADD_SEGSPACE宏有三个参数,基本名称,* /

/ *段长度(暂定)和偏移量的地址。 * /

/ * trim宏减少了最后一段的长度。 * /

/ * * /

/ *还有两个用于增加动态* /

/ *数组大小的宏,一个增加数组大小,并增加一个任意数量的* /

/ *大小。 STG_INCR_DYNARRAY宏有一个* /

/ *单个参数,即基指针。 STG_REQSZ_DYNARRAY宏* /

/ *两个参数,基指针和新大小。 * /

/ * * /

/ *注意事项:* /

/ * * /

/ *没有错误检查。用户应该智能地使用宏* /

/ *。调用后不会对* /

/ *返回值进行错误检查。所有宏调用必须后跟分号。 * /

/ * * /

/ * -------------------------- --------------------------------------- * /

# ifndef utl_stgmacros_include

#define utl_stgmacros_include

#define STG_DCL_SEGSPACE(名称,类型)\

静态类型*名称= 0; \

static size_t name ## _ size = sizeof(type); \

static size_t name ## _ alloc = 0; \

静态size_t名称## _ used = 0

#define STG_ADD_SEGSPACE(名称,偏移,长度)\

做{\

offset = name ## _ used; \

名称## _使用+ =长度; \

if(name ## _ used name ## _ alloc){\

name ## _ alloc = 2 * name ## _ alloc + length; \

name = realloc(name,name ## _ alloc * name ## _ size); \

} \

}而(0)


#define STG_TRIM_SEGSPACE(姓名,长度)\

名称## _ used - = length


#define STG_FREE_SEGSPACE(name); \

做{\

免费(姓名); \

name = 0; \

名称## _ alloc = 0; \

名称## _ used = 0; \\ /

} while(0)


#define STG_DCL_DYNARRAY(名称,类型,长度)\

静态类型* name = 0; \

static int length = 0; \

static size_t name ## _ size = sizeof(type); \

static size_t name ## _ alloc = 0; \

static int * name ## _ lenptr =& length


#define STG_INCR_DYNARRAY(name)\

do {\

(* name ## _ lenptr)++; \\ *

if(* name ## _ lenptr name ## _ alloc){\

if(name ## _ alloc< 8)name ## _ alloc = 8; \

其他名称## _ alloc * = 2; \

name = realloc(name,name ## _ alloc * name ## _ size); \

} \

}而(0)


#define STG_REQSZ_DYNARRAY(姓名,长度)\

do {\

if(length name ## _ alloc){\

name = realloc(name,length * name ## _ size) ; \

名称## _ alloc = length; \

} \

}而(0)


#define STG_FREE_DYNARRAY(姓名)\

免费(名字)$ {$

; \

name = 0; \

*名称## _ lenptr = 0; \

名称## _ alloc = 0; \\ /

}而(0)


#endif

解决方案




Richard Harter在11/08/06 13:58写道:


道歉 - 这篇文章最好用固定字体查看

和行宽> = 72.


下面是提供的C头文件的源代码套件

的存储管理宏。我正在征求意见。



请原谅我没有重复你的版权

通知。我保证不会复制代码中的任何实质部分

,并且我保证不会提供任何可能被视为衍生作品的建议




* /


/ *警告:* /

/ * * /

/ *没有错误检查。用户应该智能地使用宏* /

/ *。调用后不会对* /

/ *返回值进行错误检查。



确实,没有错误检查。例如,realloc()

故障无条件地无可挽回地泄漏内存,使用宏对程序造成损害。在我看来,

意味着有一种方法可以智能地使用它们:不要。


如果没有错误检查,包装就没用了除了

玩具程序中泄漏和碰撞并不重要 - 所以

我不会浪费时间详细研究你的工作。但是,很多东西都很突出:


- 为什么这种对宏的迷恋?为什么不使用函数?

这是过度的宏观化'正在使错误恢复

尴尬(并非不可能),而在
中做这些事情
函数上下文是相对常规的。


- 为什么使用多个自变量来描述

blob的存储?这就是结构的用途。


- 为什么在所有标识符上强制静态?可能不是一个

用户偶尔会想要外部链接,或者甚至可能是一个自动版本?


如果您决定要做一些关于处理错误的事情,我会

需要更长的时间。但是直到并且除非...


-
Er * ********@sun.com


2006年11月8日星期三14:25:50 -0500,Eric Sosman< Er ********* @ sun.com>

写道:


>

Richard Harter在11/08/06 13:58写道:


>道歉的长度 - 这篇文章最好用固定字体查看
和行宽> = 72.

下面是C头文件的源代码,它提供了一套存储管理宏。我正在征求意见。



请原谅我没有重复你的版权
通知。我保证不会复制代码的任何实质部分,并且我保证不提供任何可能被视为衍生作品的建议。



非常感谢您的体贴;特此原谅。

当然应该是衍生作品,但我认为

的改变不会减轻你的焦虑。
< blockquote class =post_quotes>
>

* /


> / *警告:* /
/ * * /
/ *没有错误检查。用户应该智能地使用宏* /
/ *。调用后不会对* /
/ *返回值进行错误检查。



确实,没有错误检查。例如,realloc()
失败无条件地无可挽回地泄漏内存,对使用宏的程序造成损害。在我看来,
意味着有一种方法可以智能地使用它们:不是。



实际上如果realloc失败,使用程序将在取消引用空指针后立即崩溃



当然,包括错误检查是可取的,但它应该做什么?

没有通用的错误检查策略。我的想法是让

使用该软件包的人自己进行错误检查。这将是

很好的评论如


/ *在这里输入你自己的错误检查realloc失败* /


>

如果没有错误检查,那么包裹是无用的,除非在玩具程序中泄漏和碰撞并不重要 - 所以
我不会浪费时间详细研究你的工作。但是,很少有东西可以突出:


- 为什么这对宏的迷恋?为什么不使用函数?

这是过度的宏观化'正在使错误恢复

尴尬(并非不可能),而在
中做这些事情
函数上下文是相对常规的。



这是另一种选择,但存在一些问题。函数有
最好是文件的本地(静态);如果没有,你需要像

句柄来避免冲突。你仍然需要在文件中创建相同的套件

全局变量。


>

- 为什么使用多个自变量来描述

blob的存储?这就是结构的用途。



点好了。在某个地方,我对自己说,自己,你这个b $ b真的应该使用结构。我还没有打扰重做它,

但我会。


>

- 为什么在所有标识符上强制静态?可能不是一个

的用户偶尔会想要外部链接,或者甚至可能是b $ b的自动版本?



问题是州。 Static给出了存储元素文件的范围。如果你需要外部链接,那么你真的想要使用函数,将它们放在自己的文件中,并使用某种句柄。所有自动购买

有点名称隔离。


>

如果你决定做关于处理错误的事情,我会再看一下。但是除非...



我决定做的是让用户自己动手。是的,因为它可以感谢你的评论和想法。


Richard Harter说:


实际上,如果realloc失败,使用程序将在取消引用空指针后立即崩溃




实际上,如果realloc失败,那么细心的程序员会检测到这个并且找到一个不涉及崩溃的方法。如果你希望人们能够智能地使用这些宏,那么

期望他们是聪明人,并且聪明的人不要忽视

通过realloc提供给他们的重要信息(例如空指针

返回值)。


-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:正常服务将尽快恢复。请不要

调整您的电子邮件客户端。


Apologies for the length - this post is best viewed with fixed font
and a line width >= 72.

Below is the source code for a C header file that provides a suite
of storage management macros. I am asking for comments on it. In
particular: Are there any gotchas that I have overlooked? Are
there any suggestions for improvements? Is there a generally
available superior packages to do the same thing with the same
general licensing? Comments on the documentation and suggestions
for improving it are welcome.

And, of course, anyone is welcome to use this little package as
they see fit.
/* ----------------------------------------------------------------- */

/* Copyright (c) 2006 by Richard Harter */
/* */
/* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */
/* conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the */
/* Software. */
/* */
/* Derived works shall include a notice that the software is a */
/* modified version of the copyrighted software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY */
/* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE */
/* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */
/* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR */
/* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR */
/* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* */
/* ----------------------------------------------------------------- */
/* */
/* This include file provides a suite of macros that simplify the */
/* management of allocatable storage. There are two groups of */
/* macros, the segmented space macros, and dynamic array macros. */
/* The segmented space macros create a sequence of segments, where */
/* the segments are all of the same type but are variable in size. */
/* The dynamic array macros create an extensible array of elements */
/* all the same size. Typically the segspace macros are used for */
/* creating blocks of storage of primitive types, e.g., ints or */
/* chars; there is no provision for indexing through the blocks. */
/* Dynamic arrays, on the other hand, are typically used for tables. */
/* */
/* All of the storage is allocated off the heap. Control data is */
/* global to the file containing the include file. All references */
/* to storage should be of the form of base+offset (e.g. array */
/* indexing) rather than pointers because the base address can */
/* can as the base is resized. Resizing is always upwards, i.e. the */
/* storage elements never decrease in size. Each separate storage */
/* unit can be invidually freed. */
/* */
/* Usage: */
/* */
/* Storage units (segmented spaces or dynamic arrays) should be */
/* declared at the file level using the STF_DCL_SEGSPACE and */
/* STG_DCL_DYNARRAY macros. Both macros take a type and a base */
/* name as arguments; in addition the STG_DCL_DYNARRAY macro has the */
/* the address of a variable that will contain the array length. */
/* The "name" argument is the address of the variable that contains */
/* the pointer to base of the storage space. */
/* */
/* There are two macros for increasing segspace storage, one to add */
/* a segment and one to trim the length of the last segment. The */
/* STG_ADD_SEGSPACE macro takes three arguments, the base name, the */
/* segment length (tentative), and the address of the offset. The */
/* trim macro reduces the length of the last segment. */
/* */
/* There are also two macros for increasing the size of dynamic */
/* arrays, one to increment the array size, and one to increase its */
/* size by an arbitrary amount. The STG_INCR_DYNARRAY macro has a */
/* single argument, the base pointer. The STG_REQSZ_DYNARRAY macro */
/* two arguments, the base pointer, and the new size. */
/* */
/* Caveats: */
/* */
/* There is no error checking. Users are expected to use the macros */
/* intelligently. The calls are not followed by error checks on the */
/* returned value. All macro calls must be followed by a semicolon. */
/* */
/* ----------------------------------------------------------------- */
#ifndef utl_stgmacros_include
#define utl_stgmacros_include

#define STG_DCL_SEGSPACE(name,type) \
static type * name = 0; \
static size_t name##_size = sizeof(type); \
static size_t name##_alloc = 0; \
static size_t name##_used = 0

#define STG_ADD_SEGSPACE(name,offset,length) \
do { \
offset = name##_used; \
name##_used += length; \
if (name##_used name##_alloc) { \
name##_alloc = 2*name##_alloc + length; \
name = realloc(name, name##_alloc*name##_size); \
} \
} while (0)

#define STG_TRIM_SEGSPACE(name,length) \
name##_used -= length

#define STG_FREE_SEGSPACE(name); \
do { \
free(name); \
name = 0; \
name##_alloc = 0; \
name##_used = 0; \
} while (0)

#define STG_DCL_DYNARRAY(name, type, length) \
static type * name = 0; \
static int length = 0; \
static size_t name##_size = sizeof(type); \
static size_t name##_alloc = 0; \
static int * name##_lenptr = &length

#define STG_INCR_DYNARRAY(name) \
do { \
(*name##_lenptr)++; \
if (*name##_lenptr name##_alloc ) { \
if (name##_alloc < 8) name##_alloc = 8; \
else name##_alloc *= 2; \
name = realloc(name,name##_alloc * name##_size); \
} \
} while (0)

#define STG_REQSZ_DYNARRAY(name,length) \
do { \
if (length name##_alloc) { \
name = realloc(name,length * name##_size); \
name##_alloc = length; \
} \
} while (0)

#define STG_FREE_DYNARRAY(name) \
do { \
free(name); \
name = 0; \
*name##_lenptr = 0; \
name##_alloc = 0; \
} while (0)

#endif

解决方案



Richard Harter wrote On 11/08/06 13:58,:

Apologies for the length - this post is best viewed with fixed font
and a line width >= 72.

Below is the source code for a C header file that provides a suite
of storage management macros. I am asking for comments on it.

Please forgive me for not repeating your copyright
notice. I promise not to reproduce any "substantial portions"
of the code, and I promise not to offer any suggestions that
might be considered "derived works."

*/

/* Caveats: */
/* */
/* There is no error checking. Users are expected to use the macros */
/* intelligently. The calls are not followed by error checks on the */
/* returned value.

Indeed, there is no error checking. For example, realloc()
failure leaks memory unconditionally and irretrievably, to the
detriment of the program using the macros. To my mind, that
means there is exactly one way to use them intelligently: don''t.

Without error-checking, the package is useless except in
toy programs where leaks and crashes don''t really matter -- so
I''m not going to waste time studying your work in detail. A
few things stood out, though:

- Why this fascination with macros? Why not use functions?
It''s the excessive macroization that''s making error recovery
awkward (not impossible), whereas doing such things in
function contexts is relatively routine.

- Why use multiple independent variables to describe the
blobs of storage? This is what structs are for.

- Why force `static'' on all the identifiers? Might not a
user occasionally want external linkage, or maybe even
an `auto'' version?

If you decide to do something about handling errors, I''ll
take a longer look. But until and unless ...

--
Er*********@sun.com


On Wed, 08 Nov 2006 14:25:50 -0500, Eric Sosman <Er*********@sun.com>
wrote:

>

Richard Harter wrote On 11/08/06 13:58,:

>Apologies for the length - this post is best viewed with fixed font
and a line width >= 72.

Below is the source code for a C header file that provides a suite
of storage management macros. I am asking for comments on it.


Please forgive me for not repeating your copyright
notice. I promise not to reproduce any "substantial portions"
of the code, and I promise not to offer any suggestions that
might be considered "derived works."

Your thoughtfullness is greatly appreciated; you are hereby forgiven.
Of course that should have been "derivative works", but I fancy that the
change would not relieve your anxieties.

>
*/

>/* Caveats: */
/* */
/* There is no error checking. Users are expected to use the macros */
/* intelligently. The calls are not followed by error checks on the */
/* returned value.


Indeed, there is no error checking. For example, realloc()
failure leaks memory unconditionally and irretrievably, to the
detriment of the program using the macros. To my mind, that
means there is exactly one way to use them intelligently: don''t.

As a practical matter if realloc fails the using program will crash
almost immediately afterwards on dereferencing a null pointer.
Including error checking is desirable of course, but what should it do?
There is no universal error checking policy. My thought here was to let
whoever used the package put in their own error checking. It would be
good to put in a comment like

/* Put in your own error check on realloc failure here */

>
Without error-checking, the package is useless except in
toy programs where leaks and crashes don''t really matter -- so
I''m not going to waste time studying your work in detail. A
few things stood out, though:

- Why this fascination with macros? Why not use functions?
It''s the excessive macroization that''s making error recovery
awkward (not impossible), whereas doing such things in
function contexts is relatively routine.

It''s an alternative, but there are some issues. The functions had
better be local to the file (static); if not, you need something like
handles to avoid conflicts. You still need to create the same of suite
of globals in the file.

>
- Why use multiple independent variables to describe the
blobs of storage? This is what structs are for.

Point well taken. Somewhere along the way I said to myself, self, you
really should have used structs. I haven''t bothered to redo it yet,
but I shall.

>
- Why force `static'' on all the identifiers? Might not a
user occasionally want external linkage, or maybe even
an `auto'' version?

The issue is state. Static gives the storage elements file scope. If
you want external linkage then you really do want to use functions, put
them in their own file, and use some kind of handle. All auto buys you
is a bit of name isolation.

>
If you decide to do something about handling errors, I''ll
take a longer look. But until and unless ...

What I decided to do was to let the user roll their own. Be that as it
may I thank you for your comments and thoughts.


Richard Harter said:

As a practical matter if realloc fails the using program will crash
almost immediately afterwards on dereferencing a null pointer.

As a practical matter, if realloc fails, the careful programmer will detect
this and find a way around that does not involve crashing. If you are
expecting people to use the macros intelligently, it is not unreasonable to
expect them to be intelligent people, and intelligent people don''t ignore
vital information supplied to them by realloc (such as a null pointer
return value).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.


这篇关于存储管理实用程序包上的RFC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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