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

Безымянный аргумент функции - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.89
120°
12 / 10 / 1
Регистрация: 01.07.2013
Сообщений: 62
03.07.2013, 12:48     Безымянный аргумент функции #1
функция принимает аргумент, но у него нет имени

C++
1
2
3
4
5
6
7
8
9
10
11
void f(int)
{
    cout << "Hello world!";
}
 
int main()
{
    int n = 10;
    f(n);
    return 0;
}
Добавлено через 13 минут
...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,354
Записей в блоге: 26
04.07.2013, 19:20     Безымянный аргумент функции #41
Цитата Сообщение от ValeryS Посмотреть сообщение
Вот вам еще одно баловство
доступ к приватной переменной
Я не уверен точно, но, думаю, стандарт никак не гарантирует, что компилятор не перемешает блоки public и private частей и расположит поля именно в том порядке, в котором они записаны в исходнике

Цитата Сообщение от Герц Посмотреть сообщение
На Mac OS X, например, я не нашел такого смещения, которое дало бы адрес неименованного аргумента. Пробовал от -512 байт до 512
Потому что параметр лежал на регистре, а не в стеке

Цитата Сообщение от Tulosba Посмотреть сообщение
так ищется оно просто
Когда ты берёшь указатель на параметр "a", то компилятор в принудительном порядке откачает его с регистра в стек. Так что ты в памяти по сути дела находишь копию параметра, а не истинный параметр, т.к. истинный параметр мог быть на регистре. В случае безымянного параметра ты взять адрес на него не сможешь, а потому с регистра в стек его никто не переложит
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryS
Модератор
6410 / 4876 / 447
Регистрация: 14.02.2011
Сообщений: 16,170
04.07.2013, 19:26     Безымянный аргумент функции #42
Цитата Сообщение от Evg Посмотреть сообщение
Я не уверен точно, но, думаю, стандарт никак не гарантирует,
про стандарт не знаю, как то не было задачи не интересовался
но эмпирическим путем замечено, что в памяти переменные лежат в том порядке в каком объявили
компиляторы Борланд, Визуал
это так, опыт дизасемблирования
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.07.2013, 19:30     Безымянный аргумент функции #43
Цитата Сообщение от Evg Посмотреть сообщение
Когда ты берёшь указатель на параметр "a", то компилятор в принудительном порядке откачает его с регистра в стек. Так что ты в памяти по сути дела находишь копию параметра, а не истинный параметр, т.к. истинный параметр мог быть на регистре. В случае безымянного параметра ты взять адрес на него не сможешь, а потому с регистра в стек его никто не переложит
Бред. Указатель должен указывать непосредственно на сущность, иначе это не указатель на неё, такое поведение неизбежно запрещено стандартом. Регистр может быть временным местом хранения данного, в том числе параметра, на время вычисления с ним, или перед помещением в стек, но потом всякое имеющее адрес данное будет сохранено в оперативу. Получается, что само звятие адреса запрещает передачу через параметр, но для анонима такой подход не возможен и запретить можно только явным выбором соглашения о вызове.
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
04.07.2013, 20:36     Безымянный аргумент функции #44
Я не уверен точно, но, думаю, стандарт никак не гарантирует, что компилятор не перемешает блоки public и private частей и расположит поля именно в том порядке, в котором они записаны в исходнике
Именно так (9.2 item 13 ISO C++):
The order of allocation of non-static data
members with different access control is unspecified (Clause 11).
Однако для Standard-Layout классов как в примере все именно так.
Dani
1263 / 621 / 50
Регистрация: 11.08.2011
Сообщений: 2,236
Записей в блоге: 2
Завершенные тесты: 1
04.07.2013, 20:49     Безымянный аргумент функции #45
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Причинами того, что, случается, в вызове функции стоит большее число параметров, чем на самом деле функция использует.
Если я правильно понял, то вот:
Предположим, что ты написал функцию MyFunc (int a, int b, int С). В ходе долгих переработок и уточнений ты понял, что переменную С мало смысла использовать, но твоей функцией уже пользуются люди и, чтобы не потерять функционал кода этих людей, ты пишешь MyFunc (int a, int b, int), чтобы поддержать использование твоей функции старой версии. Тем самым ты просто не используешь последнюю переменную.
Tulosba
:)
Эксперт С++
4382 / 3225 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
04.07.2013, 21:41     Безымянный аргумент функции #46
Цитата Сообщение от Evg Посмотреть сообщение
Так что ты в памяти по сути дела находишь копию параметра, а не истинный параметр, т.к. истинный параметр мог быть на регистре.
Т.е. соглашение вызова (cdecl в данном случае) как бы не причем, по-Вашему?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,354
Записей в блоге: 26
04.07.2013, 23:09     Безымянный аргумент функции #47
Цитата Сообщение от Tulosba Посмотреть сообщение
Т.е. соглашение вызова (cdecl в данном случае) как бы не причем, по-Вашему?
Согласно соглашению параметр приходит на таком-то регистре или стеке, но потом компилятор вправе переложить это значение в другое место. Со стека на стек перекладывать смысла нет. А вот с регистра на стек перекладывают.

Если я правильно понимаю, то cdecl означает, что все параметры будут через стеке. Так что конкретно в этом случае ты прав. Но на 100% гарантировать нельзя, т.к. компилятор в теории может переложить в другое место стека (ну захотелось так ему, в отладочных целях)
AntonChik
1083 / 581 / 21
Регистрация: 11.11.2008
Сообщений: 1,544
05.07.2013, 05:18     Безымянный аргумент функции #48
Цитата Сообщение от Tulosba Посмотреть сообщение
условную компиляцию никто не отменял. #ifdef в руки и вперед
ну это понятно. не совсем понятно только как это прикрутить.
Цитата Сообщение от Evg Посмотреть сообщение
Что конкретно ты подразумеваешь под "веткой"?
допустим у меня есть два компилятора и один исходник, в который я уже не могу вносить изменения.

C++
1
2
3
4
5
6
7
8
#define ???
 
#ifdef COMPILER1
//... код1
#endif
#ifdef COMPILER2
//... код2
#endif
осознает ли компилятор сам себя каким-либо образом?) как каждому из двух дать понять какая ему предназначена ветка кода
Tulosba
:)
Эксперт С++
4382 / 3225 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
05.07.2013, 07:49     Безымянный аргумент функции #49
Цитата Сообщение от Evg Посмотреть сообщение
Но на 100% гарантировать нельзя, т.к. компилятор в теории может переложить в другое место стека
Предлагаю еще раз обратить внимание на сообщение #15.

Цитата Сообщение от AntonChik Посмотреть сообщение
как каждому из двух дать понять какая ему предназначена ветка кода
Вот тут можно кое-что почерпнуть.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
05.07.2013, 08:01     Безымянный аргумент функции #50
Цитата Сообщение от Tulosba Посмотреть сообщение
Т.е. соглашение вызова (cdecl в данном случае) как бы не причем, по-Вашему?
А где в исходнике хоть слово про cdecl?

Добавлено через 1 минуту
Цитата Сообщение от Evg Посмотреть сообщение
Согласно соглашению параметр приходит на таком-то регистре или стеке,
cdecl[править]
Основной способ вызова для Си (отсюда название, сокращение от «c-declaration»). Аргументы передаются через стек, справа налево. Очистку стека производит вызывающая программа. Это основной способ вызова функций с переменным числом аргументов (например, printf(…))
О регистре ни слова. Передача и через стек, и через регистры - это fastcall.
fastcall[править]
Передача параметров через регистры, обычно самая быстрая; если все параметры и промежуточные результаты умещаются в регистрах, манипуляции со стеком вообще не нужны.
Fastcall не стандартизирован, поэтому используется только в функциях, которые программа не экспортирует наружу и не импортирует извне.
В компиляторе Borland, для соглашения __fastcall, называемого также register,[1] параметры передаются слева направо в eax, edx, ecx и, если параметров больше трёх, в стеке, также слева направо. Указатель стека на исходное значение возвращает вызываемая подпрограмма.
Fastcall Borland применяется по умолчанию в Delphi.
Соглашение __fastcall Microsoft, также называемое __msfastcall, в 32-хразрядной версии компилятора Microsoft,[2] а также компилятора GCC,[3] определяет передачу первых двух параметров слева направо в ecx и edx, а остальные параметры передаются справа налево в стеке. Очистку стека производит вызываемая подпрограмма.
Для x64 целей компилятор Microsoft VisualStudio 2010 CL принимает данное соглашение по умолчанию, остальные игнорируются, даже если заданы явно. Передача параметров в данном случае происходит при помощи 4х 64х разрядных регистра: rcx, rdx, r8, r9. В случае если параметров больше — остальные передаются через стек.
. В случае одного целого fascall гарантирует передачу через регистр, но только если не параметру не нужен адрес.

Добавлено через 57 секунд
Кстати, очень подозреваю, что здесь неявный fascall.

Добавлено через 3 минуты
Цитата Сообщение от Evg Посмотреть сообщение
Это не хак, а $рань господня, которая будет работать исключительно на твоём компиляторе, т.к. твой "хак" ты подогнал под поведение конкретно своего компилятора
Грязный хак как раз и должен быть не переносимым и подгоняться под конкретное сочетание компилятора, IDE, целевой опеационки и целевого "железа".
Tulosba
:)
Эксперт С++
4382 / 3225 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
05.07.2013, 08:04     Безымянный аргумент функции #51
Цитата Сообщение от taras atavin Посмотреть сообщение
А где в исходнике хоть слово про cdecl?
Было указание на VS2012. Предлагаю собрать консольный проект и убедиться, что там cdecl.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.07.2013, 14:45     Безымянный аргумент функции
Еще ссылки по теме:

C++ Auto как аргумент функции
C++ аргумент в виде шаблонной функции
C++ Третий аргумент функции sdt :: getline
Абстрактный класс, как аргумент функции C++
Аргумент argv в функции main() C++

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16935 / 5340 / 328
Регистрация: 30.03.2009
Сообщений: 14,354
Записей в блоге: 26
05.07.2013, 14:45     Безымянный аргумент функции #52
AntonChik, см. Есть ли стандартные значения для препроцессора для разных операционных систем?

Цитата Сообщение от Tulosba Посмотреть сообщение
Предлагаю еще раз обратить внимание на сообщение #15
Ещё раз повторюсь, что нормальных способов нет. Всякие читерские приёмы, которые работают в рамках одного компилятора мне ни разу не интересно обсуждать, т.к. ответ на них будет примерно такой, что залезь в отладчик и посмотри на то место, где по программным соглашениям должен лежать параметр
Yandex
Объявления
05.07.2013, 14:45     Безымянный аргумент функции
Ответ Создать тему
Опции темы

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