Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
1

Странное поведение аргументов по умолчанию

29.11.2017, 20:10. Показов 527. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вот элементарный пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
auto main(int argc, char * argv[]) -> int
{
    extern auto boxSize(int = 4, int = 4, int = 5) -> int;
    extern auto func() -> int;
    cout << boxSize() << '\n';          //выводится 80
    cout << func() << '\n';         //выводится 1000
 
    system("pause");
    return EXIT_SUCCESS;
}
 
 
auto func() -> int
{
    extern auto boxSize(int = 10, int = 10, int = 10) -> int;
    return boxSize();
}
 
 
auto boxSize(int x, int y, int z) -> int //вычисляет размер куба
{
    return x * y * z;
}
Здесь возникает вопрос, почему отрабатываются (и что удивительно правильно) два прототипа для одной и той же функции, в которых значения для аргументов по умолчанию разные?
Вроде компилятор должен возразить, указав, что аргументы по умолчанию различны, однако все работает, ну как написано.

Добавлено через 2 часа 52 минуты
Кстати, для кого то может это и не новость, а я с удивлением ещё обнаружил, что в качестве умолчальных значений для аргументов со значениями по умолчанию можно брать значения любых выражений, которые вычисляются в тип данного аргумента или хотя бы в тип, который допускает приведение в тип данного аргумента, но с одним маленьким исключением.

Все ПЕРЕМЕННЫЕ и КОНСТАНТЫ, которые используются для вычисления этих умолчальных значений, должны быть определены на глобальном уровне.

И тут снова вопрос, это так и должно быть или это специфика от Microsoft?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.11.2017, 20:10
Ответы с готовыми решениями:

Странное поведение функции с переменным количеством аргументов
Честно говоря даже не знаю где проблема, надеюсь вы поможете разобраться. Есть функция LinkStr для...

Странное расположение в памяти аргументов функции с неизвестным количество аргументов
Не могу понять, почему такая программа не работает, выдавая segmentation fault после распечатки...

Странное поведение
#include &lt;windows.h&gt; LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam);...

странное поведение
До определенного времени мой сайт получал с Яндекса почти 2к посетителей в сутки. Но в один...

7
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
29.11.2017, 20:28 2
Цитата Сообщение от Просто Саша Посмотреть сообщение
два прототипа для одной и той же функции, в которых значения для аргументов по умолчанию разные?
Потому, что они объявлены в разных областях видимости.

C++
1
2
3
4
5
6
7
void foo(int i=0);
// void foo(int i=1); // ошибка компиляции.
 
void bar()
{
    void foo(int i=3); //OK
}
Более того, объявление во внутренней области скрывает объявление во внешней:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void f(int, int x = 42);
void f();
 
int main()
{
    f();
    f(42);//OK
 
    void f();
    f();
    //f(42); //А здесь уже будет ошибка компиляции
}
 
 
void f() {}
void f(int, int) {}
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
29.11.2017, 20:33  [ТС] 3
Цитата Сообщение от avgoor Посмотреть сообщение
Более того, объявление во внутренней области скрывает объявление во внешней:
Да у Вас тут пример не на значения аргументов по умолчанию, а на перегрузку.
Это разные вещи.
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
29.11.2017, 20:40 4
Цитата Сообщение от Просто Саша Посмотреть сообщение
Да у Вас тут пример не на значения аргументов по умолчанию, а на перегрузку.
Это разные вещи.
Вы пост целиком прочитали? Первый пример тоже на перегрузку?
Второй пример показывает как объявление функций в разных областях видимости на самом деле работает
0
Вездепух
Эксперт CЭксперт С++
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,076
29.11.2017, 20:55 5
Цитата Сообщение от Просто Саша Посмотреть сообщение
Здесь возникает вопрос, почему отрабатываются (и что удивительно правильно) два прототипа для одной и той же функции, в которых значения для аргументов по умолчанию разные?
Вроде компилятор должен возразить, указав, что аргументы по умолчанию различны, однако все работает, ну как написано.
С чего бы это вдруг? Почему вы видите в этом проблему вообще?

Аргументы по умолчанию к самой функции вообще не имеют никакого отношения. Сама функция "внутри" ничего об аргументах по умолчанию не знает и не должна знать. Аргументы по умолчанию - это сущности, живущие снаружи, в том контексте из которого функция вызывается. В разных "контекстах" вы можете задавать разные наборы аргументов по умолчанию, пока они не конфликтуют друг с другом.

Причем вы можете также "добавлять" новые аргументы по умолчанию в последовательные объявления одной и той же функции в одной и той же области видимости

C++
1
2
3
4
5
6
7
8
9
10
11
int foo(int, int, int);
int a = foo(1, 2, 3);
 
int foo(int, int, int = 5);
int b = foo(1, 2); // = foo(1, 2, 5)
 
int foo(int, int = 42, int);
int c = foo(1); // = foo(1, 42, 5)
 
int foo(int = 123, int, int);
int d = foo(); // = foo(123, 42, 5)
1
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
29.11.2017, 21:07  [ТС] 6
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
С чего бы это вдруг? Почему вы видите в этом проблему вообще?
Вы значете я вообще считал, что вот эти аргументы по умолчанию, они как бы ВКОМПИЛИРОВАНЫ в функцию, но по всей видимости я ошибался.
Тем более, во всех учебниках говорится примерно следующее:

Что аргументы по умолчанию определяются только в ОДНОМ месте, а именно или в прототипе, или в заголовке функции при отсутствии прототипа, но не в обеих местах сразу, даже если значения этих аргументов полностью совпадают.


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

Мне кажется такое поведение странным. Гораздо лучше, как мне кажется, было бы то, чтобы все прототипы, неважно гле они указаны, обязаны быть согласованными друг с другом по значениям умолчальных аргументов.

Ну и второе, это то, что я всегда считал, что для умолчальных аргументов могут использоваться только литералы, ну те значения после знака равенства, а оказывается можно использовать и переменные и функции, главное, чтобы они не были локальными.
0
Вездепух
Эксперт CЭксперт С++
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,076
29.11.2017, 21:33 7
Цитата Сообщение от Просто Саша Посмотреть сообщение
Тем более, во всех учебниках говорится примерно следующее:

Что аргументы по умолчанию определяются только в ОДНОМ месте, а именно или в прототипе, или в заголовке функции при отсутствии прототипа, но не в обеих местах сразу, даже если значения этих аргументов полностью совпадают.
В этом утверждении (хоть и несколько косноязычном), речь идет об одной и той же области видимости и его следует воспринимать, как относящееся к каждому конкретному аргументу в отдельности. То есть одному и тому же аргументу нельзя в нескольких местах назначить значение по умолчанию, даже если эти значения совпадают.

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

Цитата Сообщение от Просто Саша Посмотреть сообщение
А оказывается, что немного не так. Точнее именно так, но только с поправкой на то, что вот это все находится в одной и той же области видимости.
В разных областях видимости можно творить вообще, что угодно.

Цитата Сообщение от Просто Саша Посмотреть сообщение
Мне кажется такое поведение странным. Гораздо лучше, как мне кажется, было бы то, чтобы все прототипы, неважно гле они указаны, обязаны быть согласованными друг с другом по значениям умолчальных аргументов.
Это правильно. И на практике обычно именно так и поступают, чтобы не было ненужных сюрпризов. Но возможность устроить вот такой вот "раздрай" в языке есть.
1
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
29.11.2017, 21:58  [ТС] 8
Вот уважаемый TheCalligrapher все теперь встало на свои места.
Тока хотелось бы, чтобы все вот это излагалось в учебниках и жирным шрифтом на видном месте, а не так чтобы доходить до всего самому и не быть уверенным, что может так не есть на самом деле, а то что получается может быть отнесено на специфику конкретного компилятора.
0
29.11.2017, 21:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.11.2017, 21:58
Помогаю со студенческими работами здесь

Странное поведение
У меня есть модуль, называется module.py: def input(value='',mask = None, placeholder = None,...

Странное поведение
Здравствуйте, столкнулся с проблемой и никто не может сказать в чем может быть загвоздка, сам...

Странное поведение с БД
Ребят есть CMS-ка на Ларавел, так вот там есть в админке таблица которая цепляет данные из...

Странное поведение!
Доброго времени суток! На лицо странное (на мой взгляд) поведение С++ Builder 6. Итак код:...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru