Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.73
Tamoren
0 / 0 / 0
Регистрация: 08.01.2012
Сообщений: 37
#1

Оператор -> и спецификатор класса памяти extern - C++

08.01.2012, 02:40. Просмотров 1905. Ответов 16
Метки нет (Все метки)

Оператор ->
Исходя из того, что он вообще был добавлен в язык, можно сделать вывод, что такая *struct.elem запись уже где-то используется (не для доступа к элементу elem структуры struct), и оператор -> добавлен для того чтобы избежать путаницы (и используется такая struct->elem запись). Вопрос: где используется такая *struct.elem запись?

Cпецификатор класса памяти extern
Что произойдет, если в одном месте переменная определена как int, а в другом её объявить extern volatile int? Другими словами, что произойдет при использовании extern с по-другому объявленными переменными?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.01.2012, 02:40     Оператор -> и спецификатор класса памяти extern
Посмотрите здесь:

Спецификатор автоматического класса памяти, register - C++
Прочитал: Register. Ещё один спецификатор автоматического класса памяти. Применяется к объектам, по умолчанию располагаемым в локальной...

Как грамотно убрать класс с глобальной видимости, удалив оператор extern? - C++
Пусть есть такие файлы исходного кода: main.cpp: #include "classA.h" extern classA aObj; int main() {

Спецификатор noexcept для класса "исключение" - C++
Доброго все дня! Стандартный класс std::exception имеет спецификатор noexcept для всех своих методов/операторов/конструкторов. Однако, он...

Проверка выделения памяти указателей через оператор new - C++
И так есть некая структура, экземпляр которой определён как: var ***v; Изначально заполняю экземпляр: v = new var**; // создание...

Шаблонный оператор не шаблонного класса - C++
Пытаюсь создать альтернативный оператор выделения памяти для своей библиотеки. С целью получить возможность передавать дополнительную...

Перегрузить для класса оператор == - C++
немогу написать продолжение кода... нужно написать : перегрузить для данного класса оператор ==, вычисляющий пробег автомобиля с...

Оператор this и обращение к членам класса - C++
строка this->b = new B; означает взять вдресс текущего объекта b и выделить под него память?так? class B{ public: int k; ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
08.01.2012, 02:44     Оператор -> и спецификатор класса памяти extern #2
например
Цитата Сообщение от Tamoren Посмотреть сообщение
Вопрос: где используется такая *struct.elem запись?
C
1
2
3
4
5
struct mystruct {
    int* elem;
} obj;
//...
*obj.elem = 100500;
Tamoren
0 / 0 / 0
Регистрация: 08.01.2012
Сообщений: 37
08.01.2012, 03:05  [ТС]     Оператор -> и спецификатор класса памяти extern #3
То есть если у нас есть указатель *p на структуру obj, то для доступа к её елементу element нужно использовать p->element (и компилятор сам догадается, что p - указатель, и не нужно перед p ставить *)
Если у нас есть указатель int* elem в структуре obj, то чтобы присвоить значение 100500 переменной, на которую ссылается указатель elem структуры obj нужно использовать *obj.elem = 100500.
А что если у меня есть указатель *p на элемент element структуры obj? Как мне этому елементу присвоить значение 100500? Я бы тогда здесь использовал *obj.elem = 100500. А в предыдущем получается obj.*elem = 100500...
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
08.01.2012, 04:19     Оператор -> и спецификатор класса памяти extern #4
вот зачем все усложнять, есть аксиомы которым нужно следовать, если всё поддавать сомнению то и...

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdlib.h>
#include <stdio.h>
 
struct mystruct {
    int* elem;
} obj, *pobj;
 
int main(void)
{
   obj.elem = malloc(sizeof(int));
   *obj.elem = 100500;
   printf("%d\n", *obj.elem);
   pobj = &obj;
   *pobj->elem = 100501;
   printf("%d\n", *obj.elem);
   *(*pobj).elem = 100502;
   printf("%d\n", *obj.elem);
   free(pobj->elem);
   return 0;
}
http://liveworkspace.org/code/e902e6...535ce62e385fcb
Tamoren
0 / 0 / 0
Регистрация: 08.01.2012
Сообщений: 37
08.01.2012, 06:18  [ТС]     Оператор -> и спецификатор класса памяти extern #5
Что-то я вообще не понимаю что это:
Цитата Сообщение от Jupiter Посмотреть сообщение
C
1
*(*pobj).elem = 100502;
В плюсах это ведь также выглядит?

В общем вот структура:
C++
1
2
3
    struct struct_type {
        int a, *pa;
    } str, *pstr;
C++
1
2
3
4
5
6
7
8
9
10
11
    pstr = &str;
    str.pa = &str.a;
    pstr = &str;
    str.a = 1; //Через саму структуру
    cout << str.a << ", ";
    *str.pa = 2; //Через указатель на элемент
    cout << str.a << ", ";
    pstr->a = 3;//Через указатель на структуру
    cout << str.a << ", ";
    *pstr->pa = 4;//Через указатель на структуру, в которой содержится указатель на элемент
    cout << str.a << ", ";
Вроде работает правильно. Смысл понял. Дело было в более высоком приоритете "." или "->" (над "*").
alkagolik
Заблокирован
08.01.2012, 12:53     Оператор -> и спецификатор класса памяти extern #6
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
 
struct str_type {
    int* el;
} obj, *pobj;
 
int main ( void )
{
    int x = 100500;
 
    obj.el = &x;
    pobj = &obj;
    printf("%i\n", *pobj->el );
 
    ++( *pobj->el );
    printf("%i\n", *pobj->el );
 
    ++x;
    printf("%i\n", *pobj->el );
    return 0;
}
http://liveworkspace.org/code/995898...055fc659959671
на уровне процессора ( *pobj ).el == pobj->el. "->" просто удачное решение от создателей. Чтим, помним и уважаем.

Добавлено через 5 минут
C
1
2
    printf("%i\n", *(*pobj).el );
    printf("%i\n", *pobj->el );
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
0x8048408   mov    eax,ds:0x804a01c
0x804840d   mov    eax,DWORD PTR [eax]
0x804840f   mov    edx,DWORD PTR [eax]
0x8048411   mov    eax,0x8048520
0x8048416   mov    DWORD PTR [esp+0x4],edx
0x804841a   mov    DWORD PTR [esp],eax
0x804841d   call   0x8048300 <printf@plt>
0x8048422   mov    eax,ds:0x804a01c
0x8048427   mov    eax,DWORD PTR [eax]
0x8048429   mov    edx,DWORD PTR [eax]
0x804842b   mov    eax,0x8048520
0x8048430   mov    DWORD PTR [esp+0x4],edx
0x8048434   mov    DWORD PTR [esp],eax
0x8048437   call   0x8048300 <printf@plt>
Tamoren
0 / 0 / 0
Регистрация: 08.01.2012
Сообщений: 37
08.01.2012, 22:36  [ТС]     Оператор -> и спецификатор класса памяти extern #7
Цитата Сообщение от alkagolik Посмотреть сообщение
на уровне процессора ( *pobj ).el == pobj->el. "->" просто удачное решение от создателей. Чтим, помним и уважаем.
Точно, то что надо! Спасибо!

Ну а ассемблер я пока не пойму

Добавлено через 6 часов 16 минут
А как насчет спецификатора класса памяти extern?
alex_x_x
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
08.01.2012, 22:51     Оператор -> и спецификатор класса памяти extern #8
Цитата Сообщение от Tamoren Посмотреть сообщение
Что произойдет, если в одном месте переменная определена как int, а в другом её объявить extern volatile int? Другими словами, что произойдет при использовании extern с по-другому объявленными переменными?
может схавать - зависит от компилятора, но поведение неопределенное
Tamoren
0 / 0 / 0
Регистрация: 08.01.2012
Сообщений: 37
08.01.2012, 23:46  [ТС]     Оператор -> и спецификатор класса памяти extern #9
То есть переменные, объявленные с extern и без должны иметь одинаковый тип, иначе я рискую нарваться на ошибку или вообще повредить память?
Evg
Эксперт CАвтор FAQ
17470 / 5708 / 363
Регистрация: 30.03.2009
Сообщений: 15,670
Записей в блоге: 26
09.01.2012, 12:43     Оператор -> и спецификатор класса памяти extern #10
Цитата Сообщение от Tamoren Посмотреть сообщение
Что произойдет, если в одном месте переменная определена как int, а в другом её объявить extern volatile int? Другими словами, что произойдет при использовании extern с по-другому объявленными переменными?
Конкретно в данном случае де-юре сам дурак, потому что программист обязан следить за корректностью описаний. Де-факто в случае языка Си скорее всего все компиляторы сожрут это, но в случае Си++, возможно, "int x" и "volatile int x" могут трактоваться как два разных объекта

Добавлено через 29 секунд
Цитата Сообщение от Tamoren Посмотреть сообщение
То есть переменные, объявленные с extern и без должны иметь одинаковый тип, иначе я рискую нарваться на ошибку или вообще повредить память?
Грубо говоря, да
alex_x_x
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
09.01.2012, 14:24     Оператор -> и спецификатор класса памяти extern #11
Цитата Сообщение от Evg Посмотреть сообщение
но в случае Си++, возможно, "int x" и "volatile int x" могут трактоваться как два разных объекта
ну вот, как не странно линковщик g++'а съел определение double x; и объявление extern int x;
скомпилировал и слинковал без проблем, что немного пугает
Evg
Эксперт CАвтор FAQ
17470 / 5708 / 363
Регистрация: 30.03.2009
Сообщений: 15,670
Записей в блоге: 26
09.01.2012, 15:20     Оператор -> и спецификатор класса памяти extern #12
Цитата Сообщение от alex_x_x Посмотреть сообщение
ну вот, как не странно линковщик g++'а съел определение double x; и объявление extern int x;
скомпилировал и слинковал без проблем, что немного пугает
Возможно, я и гоню. Просто функция с параметрами разных типов манглируется, а вот манглируются ли переменные - хз. Просто какая-то мысль вертится в голове на предмет того, что с модификатором где-то что-то по другому трактовалось, но не помню где
LosAngeles
Заблокирован
09.01.2012, 19:07     Оператор -> и спецификатор класса памяти extern #13
Цитата Сообщение от alex_x_x Посмотреть сообщение
может схавать - зависит от компилятора, но поведение неопределенное
от компилятора это не зависит, компилятор, встретив переменную допустим extern int x, поместит её в таблицу символов, если пройтись по такому объектному файлу objdump, то он покажет смещение *UND* для такой переменной и в коде везде будет обращаться с ней как с обычным интом, просто пока неизвестно его смещение. Во втором модуле можно определить этот самый x причём чем угодно, необязательно интом, можно структурой или указателем на функцию, линкеру это по барабану, ему нужно только смещение и имя идентификатора, во внутренние дела модуля он не лезет. Главное чтобы все были определены по разу, он просто слепит все модули подставив соответсвующие адреса. Он не делает проверку типов. Так что extern volatileint по всей видимости означает что внутри этого модуля с этим импортированным символом будут обращаться как с int volatile, но чем он является на самом деле неизвестно. Конечно это всё зависит от ABI, может на какой нибудь платформе с каким то экзотическим форматом файлов и делается проверка типов, но я с такими не сталкивался. Удобно кстати задефайнить extern в PUBLIC, а static в PRIVATE, тогда становится нагляднее что экспортируется


в системном программировании кстати применяется иногда такой трюк с extern. Иногда нужно например убедиться чтобы размер загрузочного образа был в рамках приличного на этапе компиляции, тогда пользуются тем фактом, что нельзя создать массив отрицательного размера
C
1
extern int dummy[sizeof(image) > LIMIT ? 100 : -100];
а потом определяют его где-нибудь dummy как short int
alex_x_x
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
09.01.2012, 19:10     Оператор -> и спецификатор класса памяти extern #14
LosAngeles, ок, от линковщика, но смысла это не меняет
LosAngeles
Заблокирован
09.01.2012, 19:22     Оператор -> и спецификатор класса памяти extern #15
меняет, ТС запугали что ктото чтото не пропустит, на самом деле пропустит всё. В данном конкретном случае:
Цитата Сообщение от Tamoren Посмотреть сообщение
Что произойдет, если в одном месте переменная определена как int, а в другом её объявить extern volatile int? Другими словами, что произойдет при использовании extern с по-другому объявленными переменными?
не пройзойдёт ничего, где-то переменная будет трактоваться как volatile, а где-то нет, это странно конечно но формально правильно
alex_x_x
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
09.01.2012, 19:27     Оператор -> и спецификатор класса памяти extern #16
LosAngeles, скорее всего да, но ровно также можно объявить и определить переменную с принципиально разными типами
и при доступе к ней получить неправильное значение и с некоторой вероятностью программное прерывание (если размеры объявления и определения не будут совпадать)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.01.2012, 21:40     Оператор -> и спецификатор класса памяти extern
Еще ссылки по теме:

Оператор присвоения для класса - C++
Никак не получается написать оператор присвоения. Помогите пожалуйста! #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std;...

Реализовать оператор умножения класса - C++
Только начал работать с классами и мне не совсем понятно, как работать с операторами, вот что у меня получилось: class Matrix { ...

оператор присваивания для класса - C++
Помогите, пожалуйста. Требуется написать оператор присваивания для данного класса class ARRAY{ int size; double **m; public: ...

Оператор new. Чему равны эллемнты выделенной памяти по умолчанию? - C++
Пишу на Visual C++ 2012 Есть буффер 100*100 байт char *buf=new char; пока он не занимает память... далее пишу: buf=255; ...

Оператор new гарантирует алокацию непрерывного блока памяти? (выравнивания) - C++
Ну собственно сабж. Делаю int* data = new data; Оператор new гарантирует, что в памяти выделится непрерывный кусочек, в котором один...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17470 / 5708 / 363
Регистрация: 30.03.2009
Сообщений: 15,670
Записей в блоге: 26
09.01.2012, 21:40     Оператор -> и спецификатор класса памяти extern #17
Цитата Сообщение от alex_x_x Посмотреть сообщение
LosAngeles, скорее всего да, но ровно также можно объявить и определить переменную с принципиально разными типами
и при доступе к ней получить неправильное значение и с некоторой вероятностью программное прерывание (если размеры объявления и определения не будут совпадать)
Можно. Плохо будет только тогда, когда реальная переменная меньше, чем то, что описано в extern'е, потому что в этом случае произойдёт выход за границу переменной и может затереться что-то полезное

C
1
2
3
4
5
6
7
8
9
10
11
12
13
/* Файл t1.c */
 
extern long long x;
 
extern void func (void);
 
int
main (void)
{
  x = 0x1122334455667788ull;
  func();
  return 0;
}
C
1
2
3
4
5
6
7
8
9
10
11
12
/* Файл t2.c */
 
#include <stdio.h>
 
int x = 0;
int y = 0;
 
void
func (void)
{
  printf ("x=0x%x, y=0x%x\n", x, y);
}
Код
$ gcc t1.c t2.c      
$ ./a.out 
x=0x55667788, y=0x11223344
Здесь мы затёрли переменную "y"
Yandex
Объявления
09.01.2012, 21:40     Оператор -> и спецификатор класса памяти extern
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru