简体   繁体   English

将结构内的指针初始化为编译时常量

[英]Initialize pointer inside struct as compile-time constant

I would like to know what the legal way of defining a constant struct that has a pointer as one of it's elements.我想知道定义具有指针作为其元素之一的常量struct的合法方式是什么。 Looking at this post ( Initializer element is not constant in C ) I can see the following:看这篇文章( Initializer element is not constant in C )我可以看到以下内容:

6.6 Constant expressions 6.6 常量表达式

(7) More latitude is permitted for constant expressions in initializers. (7) 初始化器中的常量表达式允许更大的自由度。 Such a constant expression shall be, or evaluate to, one of the following:这样的常量表达式应为或评估为以下之一:

— an arithmetic constant expression, — 算术常数表达式,

— a null pointer constant, — 一个 null 指针常量,

— an address constant, or — 地址常数,或

— an address constant for an object type plus or minus an integer constant expression. — object 类型的地址常量加上或减去 integer 常量表达式。

(8) An arithmetic constant expression shall have an arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, and sizeof expressions. (8) 算术常量表达式应具有算术类型,且操作数应仅为 integer 常量、浮点常量、枚举常量、字符常量和 sizeof 表达式。 Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof operator whose result is an integer constant.算术常量表达式中的强制转换运算符只能将算术类型转换为算术类型,除非作为 sizeof 运算符的操作数的一部分,其结果是 integer 常量。

My question is if the following is well defined according to the (intersection of the C89 and C99) standard.我的问题是以下是否根据(C89 和 C99 的交集)标准得到了很好的定义。 The contents of test.h : test.h的内容:

#ifndef TEST_H
#define TEST_H

typedef struct _poly {
    unsigned long int degree;
    signed long int *coeffs;
} poly;

extern const poly my_poly;
extern void print_poly(poly p);

#endif

Contents of test.c : test.c的内容:

#include <stdio.h>
#include "test.h"

static signed long int coeffs[3] = {1L, 2L, 3L};
const poly my_poly = {2UL, coeffs};

void print_poly(poly p)
{
    /* Irrelevant mumbo-jumbo goes here. */
}

Contents of main.c : main.c的内容:

#include "test.h"

int main(void)
{
    print_poly(my_poly);
    return 0;
}

Compiling on Debian 11 with gcc (and -Wall -Wextra -Wpedantic -std=c89 enabled), clang (with -Weverything -std=c89 enabled), tcc (with -Wall -std=c89 enabled), and pcc (with -std=c89 enabled) produces no warnings and no errors and runs as expected. Compiling on Debian 11 with gcc (and -Wall -Wextra -Wpedantic -std=c89 enabled), clang (with -Weverything -std=c89 enabled), tcc (with -Wall -std=c89 enabled), and pcc (with -std=c89 enabled) 不会产生警告和错误并按预期运行。 Is the code:是代码:

static signed long int coeffs[3] = {1L, 2L, 3L};
const poly my_poly = {2UL, coeffs};

the correct way to initialize a constant struct that has a pointer as one of its member so that it is a compiler-time constant?初始化具有指针作为其成员之一的常量结构的正确方法,使其成为编译器时常量? It seems to follow the rule that it be an address constant, but I'm not sure.它似乎遵循它是地址常量的规则,但我不确定。

As the question notes, an initializer may be an address constant.正如问题所指出的,初始化程序可能是地址常量。

C 2018 6.6 9 says “An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; C 2018 6.6 9 says “An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; it shall be created explicitly using the unary & operator or an integer constant cast to pointer type, or implicitly by the use of an expression of array or function type…”它应使用一元&运算符或转换为指针类型的 integer 常量显式创建,或通过使用数组表达式或 function 类型隐式创建……”

In const poly my_poly = {2UL, coeffs};const poly my_poly = {2UL, coeffs}; , coeffs is an array of static storage duration, and it is implicitly converted to a pointer to its first element (per C 2018 6.3.2.1 3). , coeffs是 static 存储持续时间的数组,它被隐式转换为指向其第一个元素的指针(根据 C 2018 6.3.2.1 3)。 Therefore, the result of the conversion, effectively &coeffs[0] , is an address constant and may be used as an initializer.因此,转换的结果,实际上是&coeffs[0] ,是一个地址常数,可以用作初始化器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM