"私人和QU​​OT;在C结构成员常量 [英] "Private" struct members in C with const

查看:76
本文介绍了"私人和QU​​OT;在C结构成员常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了有一个干净的code,使用一些OO的概念是很有用的,即使是在C.
我经常写了一个对h和.c文件的模块。问题是,该模块的用户要小心,因为在C.不存在私有成员的使用平普尔成语或抽象数据类型是好的,但它增加了一些code和/或文件,并要求较重code。我讨厌使用访问时,我并不需要一个。

In order to have a clean code, using some OO concept can be usefull, even in C. I often write modules made of a pair of .h and .c files. The problem is that the user of the module have to be careful, since private members don't exist in C. The use of the pimpl idiom or abstract data types is ok, but it adds some code and/or files, and requires a heavier code. I hate using accessor when I don't need one.

下面是一个想法至极提供了一种方法,使编译器抱怨无效获得私人的成员,只有少数几个额外的code。该思想是定义相同的结构两次,但与一些额外的常量添加的模块的用户

Here is a idea wich provides a way to make the compiler complain about invalid access to "private" members, with only a few extra code. The idea is to define twice the same structure, but with some extra 'const' added for the user of the module.

当然,在私的成员写依旧可能带有一个演员。但问题是只避免从模块的用户错误,不以安全地保护存储器

Of course, writing in "private" members is still possible with a cast. But the point is only to avoid mistakes from the user of the module, not to safely protect memory.

/*** 2DPoint.h module interface ***/
#ifndef H_2D_POINT
#define H_2D_POINT

/* 2D_POINT_IMPL need to be defined in implementation files before #include */
#ifdef 2D_POINT_IMPL
#define _cst_
#else
#define _cst_ const
#endif

typedef struct 2DPoint
{
    /* public members: read and write for user */
    int x;

    /* private members: read only for user */
    _cst_ int y;
} 2DPoint;

2DPoint *new_2dPoint(void);
void delete_2dPoint(2DPoint **pt);
void set_y(2DPoint *pt, int newVal);


/*** 2dPoint.c module implementation ***/
#define 2D_POINT_IMPL
#include "2dPoint.h"
#include <stdlib.h>
#include <string.h>

2DPoint *new_2dPoint(void)
{
    2DPoint *pt = malloc(sizeof(2DPoint));
    pt->x = 42;
    pt->y = 666;

    return pt;
}

void delete_2dPoint(2DPoint **pt)
{
    free(*pt);
    *pt = NULL;
}

void set_y(2DPoint *pt, int newVal)
{
    pt->y = newVal;
}

#endif /* H_2D_POINT */


/*** main.c user's file ***/
#include "2dPoint.h"
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    2DPoint *pt = new_2dPoint();

    pt->x = 10;     /* ok */
    pt->y = 20;     /* Invalid access, y is "private" */    
    set_y(pt, 30);  /* accessor needed */
    printf("pt.x = %d, pt.y = %d\n", pt->x, pt->y);  /* no accessor needed for reading "private" members */

    delete_2dPoint(&pt);

    return EXIT_SUCCESS;
}

而现在,这里是一个问题:这是招行与C标准?
它正常工作与海湾合作委员会,编译器不会抱怨什么,即使有一些严格的旗帜,但我怎么能肯定这是真的OK?

And now, here is the question: is this trick OK with the C standard? It works fine with GCC, and the compiler doesn't complain about anything, even with some strict flags, but how can I be sure that this is really OK?

推荐答案

这违反了Ç2011 6.2.7 1。

This violates C 2011 6.2.7 1.

6.2.7 1要求在不同的转换单元的结构相同的两个定义具有兼容的类型。它不允许有常量中的一个而不是其他。

6.2.7 1 requires that two definitions of the same structure in different translation units have compatible type. It is not permitted to have const in one and not the other.

在一个模块,您可能需要这些对象之一的引用,成员似乎是const的编译器。当编译器中的其它模块写入调用的功能,它可以由在寄存器或其它高速缓存或从后面的源$ C ​​$ C比的函数调用部分或完全评估前pressions const的成员持有的值。然后,当函数修改构件和回报,原始模块将不会有改变的值。更糟的是,它可以使用更改后的值和旧值的组合。

In one module, you may have a reference to one of these objects, and the members appear to be const to the compiler. When the compiler writes calls to functions in other modules, it may hold values from the const members in registers or other cache or in partially or fully evaluated expressions from later in the source code than the function call. Then, when the function modifies the member and returns, the original module will not have the changed value. Worse, it may use some combination of the changed value and the old value.

这是编程非常不合适。

这篇关于&QUOT;私人和QU​​OT;在C结构成员常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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