Является ли этот дополнительный const на внешнем UB? - PullRequest
2 голосов
/ 02 октября 2019

У меня есть следующее:

//h.h file
#pragma once
struct A { int x; };

//a.c file
#include "h.h"
struct A* a;

//b.c
#include "h.h"
extern struct A* const a;
int main() {}

Я добавил дополнительную const в extern декларацию. Добавление этого const будет UB?

Если это не UB, то, как показано ниже, внутри main будет UB?

(*(struct A**)&a) = malloc(sizeof(struct A));

Ответы [ 2 ]

2 голосов
/ 03 октября 2019

Рассмотрим следующую единицу компиляции:

#include "h.h"
extern struct A* const a;
void externalFunction(void);
int myFunction(void)
{
  struct A *p1,*p2;
  p1 = a;
  externalFunction();
  p2 = a;
  return p2-p1;
}

Стандарт позволит компилятору предполагать на основе директивы const, что значение a не будет изменено какследствие вызова на externalFunction. Обратите внимание, что не предпринимается никаких усилий, чтобы рассмотреть вопрос о том, могут ли быть преимущества, если учесть, что внешняя функция может изменить a. Например, на некоторых платформах a обычно может быть защищен от записи, но внешняя функция (возможно, написанная на другом языке) может отключить защиту от записи, изменить a и затем снова включить защиту. Будет ли полезно, чтобы реализация учитывала такие возможности, будет зависеть от ряда целей, для которых реализация заявляет, что она подходит, о чем Комитет не может знать, но о каких авторах компиляторов следует.

2 голосов
/ 02 октября 2019

Да. Из Приложения J.2:

  • Два объявления одного и того же объекта или функции указывают несовместимые типы (6.2.7).

И 6.2.7 ¶2:

Все объявления, которые ссылаются на один и тот же объект или функцию, должны иметь совместимый тип;в противном случае поведение не определено.

И 6.7.3 :10:

Для совместимости двух квалифицированных типов оба должны иметь идентично квалифицированную версию совместимоготип;порядок определения типа в списке спецификаторов или определителей не влияет на указанный тип.

...