грабли
От: Аноним  
Дата: 15.04.10 12:57
Оценка: 32 (1)
Привет всем
есть код типа
char MYTABLE [10][10][1024]; в одном cpp

extern char MYTABLE [10][10][130]; в другом cpp

на какие грабли попаду ?
Re: грабли
От: Sergey Chadov Россия  
Дата: 15.04.10 13:11
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>есть код типа

А>char MYTABLE [10][10][1024]; в одном cpp

А>extern char MYTABLE [10][10][130]; в другом cpp


А>на какие грабли попаду ?


На детские
Re: грабли
От: vpchelko  
Дата: 15.04.10 13:12
Оценка:
Здравствуйте, Аноним, Вы писали:

А>char MYTABLE [10][10][1024]; в одном cpp


А>на какие грабли попаду ?

А программа вообще запустится?
Сало Украине, Героям Сала
Re: грабли
От: Alexander G Украина  
Дата: 15.04.10 13:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>на какие грабли попаду ?


ODR нарушение
Русский военный корабль идёт ко дну!
Re[2]: грабли
От: uzhas Ниоткуда  
Дата: 15.04.10 14:06
Оценка: 5 (1)
Здравствуйте, Alexander G, Вы писали:
AG>ODR нарушение
ну почему же?
extern char MYTABLE [10][10][130]; — это не definition, а declaration
Re[3]: грабли
От: Кодт Россия  
Дата: 15.04.10 14:48
Оценка:
Здравствуйте, uzhas, Вы писали:

AG>>ODR нарушение

U>ну почему же?
U>extern char MYTABLE [10][10][130]; — это не definition, а declaration

Опаньки! Дырка в стандарте! Действительно, ODR не распространяется на объявления.
Перекуём баги на фичи!
Re[3]: грабли
От: uzhas Ниоткуда  
Дата: 15.04.10 14:56
Оценка:
Погуглил немного, однозначного ответа не нашел
Склоняюсь к такой точке зрения:

3.1.2.6 Compatible type and composite type

Two types have compatible type if their types are the same.
Additional rules for determining whether two types are compatible are
described in $3.5.2 for type specifiers, in $3.5.3 for type
qualifiers, and in $3.5.4 for declarators. /16/ Moreover, two
structure, union, or enumeration types declared in separate
translation units are compatible if they have the same number of
members, the same member names, and compatible member types; for two
structures, the members shall be in the same order; for two
enumerations, the members shall have the same values.

All declarations that refer to the same object or function shall
have compatible type; otherwise the behavior is undefined.

Надеюсь, это правомерно применять к C++
Re[4]: грабли
От: Masterkent  
Дата: 15.04.10 21:45
Оценка: 40 (2)
В данном случае применяются правила 3.5/9 и 3.5/10 (см. также 3/7 и 3.5/4). Однако я не вижу смысла в понятии связывания имён (прим.: имена сущностей с разным связыванием могут совпадать).
Re[4]: грабли
От: achp  
Дата: 15.04.10 22:06
Оценка: 9 (2)
Здравствуйте, uzhas, Вы писали:

U>Надеюсь, это правомерно применять к C++


В Си++ более сложные правила, касающися связывания имён. В данном случае работает 3.5(10):
[quote]
После всех замен типов (в ходе которых псевдонимы typedef (7.1.3) заменяются своими определениями) типы, указанные всеми объявлениями, относящимися к данной функции или объекту, должны быть идентичны, за тем исключением, что объявления массива могут указывать типы массивов, расходящиеся друг с другом в факте наличия или отсутствия старшей размерности (8.3.4). Нарушение этого правила идентичности типов не требует диагностики.
[/quote]
Re[5]: грабли
От: Masterkent  
Дата: 15.04.10 22:37
Оценка: +2
achp:

A> Нарушение этого правила идентичности типов не требует диагностики.


Это автоматически подразумевает undefined behavior для данного случая (см. [defns.undefined])
Re: грабли
От: MasterZiv СССР  
Дата: 16.04.10 08:28
Оценка:
Аноним 360 wrote:

> extern char MYTABLE [10][10][130]; в другом cpp

>
> на какие грабли попаду ?

На все, которые только можно.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: грабли
От: uzhas Ниоткуда  
Дата: 16.04.10 08:33
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>На все, которые только можно.

Ну не надо драматизировать =)
на практике, я думаю, больно не будет. Всего лишь sizeof выдаст неверный результат.
Куда больнее обычно вызов виртуальной функции у нулевого указателя =)
Re[3]: грабли
От: Alexander G Украина  
Дата: 16.04.10 08:42
Оценка:
Здравствуйте, uzhas, Вы писали:

MZ>>На все, которые только можно.

U>Ну не надо драматизировать =)
U>на практике, я думаю, больно не будет. Всего лишь sizeof выдаст неверный результат.

На практике я предположил, что в студии не слинкуется: студия кодирует размер параметров в имени для компонощика для __stdcall, так должна и с этой ситуацией так же справиться. И таки угадал

U>Куда больнее обычно вызов виртуальной функции у нулевого указателя =)


Больнее вызов виртуальной функции у ненулевого указателя на удалённый объект. Там, де был vtable указатель может быть другой указатель на что-то другое, и оно таки вызовется, и отформатирует диск D:
Русский военный корабль идёт ко дну!
Re[4]: грабли
От: uzhas Ниоткуда  
Дата: 16.04.10 08:50
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>На практике я предположил, что в студии не слинкуется: студия кодирует размер параметров в имени для компонощика для __stdcall, так должна и с этой ситуацией так же справиться. И таки угадал

Точно, ну так это совсем не больно =)
Вот gcc у меня слинковал. В рантайме, думаю, всё будет хорошо)
Re[5]: грабли
От: Alexander G Украина  
Дата: 16.04.10 09:01
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Вот gcc у меня слинковал. В рантайме, думаю, всё будет хорошо)


Элемент, записаный по одному индексу где-то прочитается по другому индексу. Хорошо.
Русский военный корабль идёт ко дну!
Re: 2all
От: Pavel Dvorkin Россия  
Дата: 16.04.10 09:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет всем

А>есть код типа
А>char MYTABLE [10][10][1024]; в одном cpp

А>extern char MYTABLE [10][10][130]; в другом cpp


А>на какие грабли попаду ?


Слегка упрощу пример

char MYTABLE [10][10];

extern char MYTABLE [10][5];

В действительности есть массив , 10 строк, 10 столбцов. Но во втором файле считают. что он из 10 строк и 5 столбцов.

Обращение во втором файле

к MYTABLE[0][0] пройдет безболезненно
к MYTABLE[0][1] пройдет безболезненно
...
к MYTABLE[0][4] пройдет безболезненно

к MYTABLE[1][0] приведет к тому, что реально будет изменен элемент [0][5]
к MYTABLE[1][1] приведет к тому, что реально будет изменен элемент [0][6]
...
к MYTABLE[1][4] приведет к тому, что реально будет изменен элемент [0][9]

и т.д.

Но в С++ это, действительно, не скомпилируется. А вот в С скомпилируется.

UB никакого не будет.

Это не значит, что я призываю так писать код
With best regards
Pavel Dvorkin
Re[2]: 2all
От: Sni4ok  
Дата: 16.04.10 09:20
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Но в С++ это, действительно, не скомпилируется. А вот в С скомпилируется.


как так не скомпилируется, это 2 еденицы компиляции- отлично скомпелируется
Re[3]: 2all
От: Pavel Dvorkin Россия  
Дата: 16.04.10 09:23
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Но в С++ это, действительно, не скомпилируется. А вот в С скомпилируется.


S>как так не скомпилируется, это 2 еденицы компиляции- отлично скомпелируется


пардон, не слинкуется.
With best regards
Pavel Dvorkin
Re[2]: 2all
От: uzhas Ниоткуда  
Дата: 16.04.10 09:50
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>к MYTABLE[1][0] приведет к тому, что реально будет изменен элемент [0][5]
действительно, а я что-то не подумал =\ коряво всё будет работать. это уже больновато))
PD>UB никакого не будет.
в разделе C\C++ принято обмениваться ссылками на стандарт) вы не согласны с ранее приведенными ссылками на UB и готовы предоставить контр-аргументы?
Re[3]: 2all
От: Pavel Dvorkin Россия  
Дата: 16.04.10 10:35
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, Pavel Dvorkin, Вы писали:

PD>>к MYTABLE[1][0] приведет к тому, что реально будет изменен элемент [0][5]
U>действительно, а я что-то не подумал =\ коряво всё будет работать. это уже больновато))

Коряво, да. Не спорю. Но работать будет.

PD>>UB никакого не будет.

U>в разделе C\C++ принято обмениваться ссылками на стандарт) вы не согласны с ранее приведенными ссылками на UB и готовы предоставить контр-аргументы?

Ну если принято, то это очень хорошо. Но я таких обязательств не давал, да и не большой знаток я стандарта

Обоснование очень простое. В С нет никаких двумерных массивов. Есть одномерные массивы, элементами которых могут быть одномерные массивы в том числе. А во-вторых, элементы массива лежат в памяти подряд. Все остальное следует из этого.

Если тут будет UB (в том примере, что я привел) — пожалуйста, аргументируйте, где и как.

Кстати, почти того же можно было бы добиться и проще. С одним файлом


char a[10][10];
typedef char (*PTR)[5];

int main(int argc, char* argv[])
{
    PTR p = (PTR) a;
    p[19][0] = 100; // a[10][4] = 100;
    return 0;
}


А можно и так

char a[10][10];

int main(int argc, char* argv[])
{
    char* pp = (char*) a;
    pp[99] = 100; // a[9][9] = 100;
    return 0;
}
With best regards
Pavel Dvorkin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.