LINUX.ORG.RU

Ответ на: комментарий от Obey-Kun

Если в заголовочном файле есть определение функции смысл давать её объявление в теле другой функции?

mskmsk1985
() автор топика
Ответ на: комментарий от LamerOk

Скрыть что от чего, если определения выдны в глобальной области видимости?

mskmsk1985
() автор топика
Ответ на: makefile от rudnykiv

определение и реализация - разные вещи.
тем не менее, вы правы в своём дополнении к остальным ответам :)

xydo ★★
()
Ответ на: makefile от rudnykiv

>реализация g() в другом *.cpp файле и линковать их вместе. не то?

компилятору нужно знать, что за g() и с чем ее едят. люди, вы что, только С начали учить?

lester_dev ★★★★★
()

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

З.Ы. Товарищи, вы меня пугаете. Где вы тут С увидели? о_О

roof ★★
()

А разве в C можно определять функции внутри функций? По-моему, все функции находятся в глобальном пространстве имен.

annoynimous ★★★★★
()
Ответ на: комментарий от annoynimous

В С можно внутри функции описать прототип другой функции (как это показано в топике), но нельзя имплементировать одну функцию внутри другой.

ddos3
()

Не могли бы вы уточнить, что вы подразумеваете под термином «определять» и каких целей пытаетесь достичь?

Если я правильно понял, вы хотите создать функцию, предназначеную исключительно для внутреннего использования. В таком случае, вам стоит описать ее как локальную для данной единицы компилляции, используя ключевое слово static или безымянное пространство имен (С++).

ddos3
()
Ответ на: комментарий от ddos3

пример:

// скрытие функции используя ключевое слово static
// эта функция видна только из того c/cpp файла, в котором она описана
static int g1()
{
    return 1;
}

// скрытие функции используя безымянное пространство имен
// эта функция видна только из того cpp файла, в котором она описана
namespace 
{
    int g2()
    {
        return 2;
    }
}

// эта функция находится в глобальном пространстве имен,
// и может быть использована из любого места в коде
void f()
{
    std::cout << g1() << std::endl;
    std::cout << g2() << std::endl;
} 
ddos3
()
Ответ на: комментарий от ddos3

Под термином «определять» подразумевается определение функции (имплементировать, реализовать), в отличие от «объявлять» - давать компилятору минимальную информацию о типе возвращаемого значения и типах и числе параметров. Суть вопроса: где должна быть имплементация, если объявление находится в теле другой функции? Ответ: где угодно, где это позволено синтаксисом языка (в теле другой функции, например, не позволено), главное чтобы при линковке тело функции оказалось в одном из линкуемых файлов. При объявлении функции в теле другой функции ее область видимости будет ограничена этим самым телом (от объявления и до символа «}» в конце функции). В приведенном вами примере видимость ограничена единицей компиляции, что, конечно же, совсем другое дело :)

Прошу прощения за многабукаф, в конце рабочего дня мысли компактно уже не выражаются...

roof ★★
()
Ответ на: комментарий от lester_dev

смотри еще раз на код ТС. прототип g() описан в функции f()

rudnykiv
()
Ответ на: комментарий от roof

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

функция будет видна в глобальном пространстве имен от определения и ниже.

ddos3
()
Ответ на: комментарий от ddos3

А вот ничего подобного!

roof:~/work/prog/cpp/sb$ cat fg.cpp 
#include <iostream>

void f()
{
  int g();
  std::cout<<g()<<std::endl;
}

int h()
{
  return g(); 
}
roof:~/work/prog/cpp/sb$ g++ -c fg.cpp -o fg.o
fg.cpp: In function ‘int h()’:
fg.cpp:11: ошибка: нет декларации ‘g’ в этой области видимости
roof ★★
()
Ответ на: комментарий от lester_dev

в старом Си компилятору как раз не нужно было знать «что за g()».
так что ваше обращение в первую очередь нужно применить к вам))

xydo ★★
()
Ответ на: комментарий от xydo

>в старом Си компилятору как раз не нужно было знать «что за g()».

сударь, баловаться сиропом от кашля изволите ли?

Как вы без объявления функции будете использовать эту функцию?

lester_dev ★★★★★
()
Ответ на: комментарий от lester_dev

Как вы без объявления функции будете использовать эту функцию?

Учить С, шагом А-А-АРШ!

int
main()
{
    printf("Hello, world!\n");
    return 0;
}

По-твоему, оно не соберётся, потому что printf нигде не объявлен, чтоли?

kemm
()
Ответ на: комментарий от kemm

>По-твоему, оно не соберётся, потому что printf нигде не объявлен, чтоли?

а если вместо printf будет what_the_fuck_is_this_function(«Hello, world!\n»)?

lester_dev ★★★★★
()
Ответ на: комментарий от kemm

Извините, что вмешиваюсь, но

По-твоему, оно не соберётся, потому что printf нигде не объявлен, чтоли?


а разве соберётся? Чёрт, похоже придётся всё с начала учить.

stormy
()
Ответ на: комментарий от stormy
int 
main() 
{ 
    printf("Hello, world!\n"); 
    return 0; 
}
gcc main.c
main.c: In function ‘main’:
main.c:4: warning: incompatible implicit declaration of built-in function ‘printf’
g++ main.cpp
main.cpp: In function ‘int main()’:
main.cpp:4: error: ‘printf’ was not declared in this scope
Zodd ★★★★★
()
Ответ на: комментарий от lester_dev

>> По-твоему, оно не соберётся, потому что printf нигде не объявлен, чтоли?

а если вместо printf будет what_the_fuck_is_this_function(«Hello, world!\n»)?

И что? Чем what_the_fuck_is_this_function хуже printf? Ещё раз говорю — учи С. Ты либо не в курсе, что отсутствие объявления в С не является ошибкой, либо путаешь объявление с определением.

kemm
()
Ответ на: комментарий от Zodd

Спасибо, кэп! Я, какбэ, иллюстрировал неправоту утверждающих, что в C отсутствим объявления является ошибкой.

kemm
()
Ответ на: комментарий от kemm

Ты либо не в курсе, что отсутствие объявления в С не является ошибкой, либо путаешь объявление с определением.

ТС сам вроде путает это. Не понятно чего он хочет.

Zodd ★★★★★
()
Ответ на: комментарий от Zodd

> ТС сам вроде путает это. Не понятно чего он хочет.

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

kemm
()

Это нужно, чтобы не включать лишний раз объемистые хедеры в исходник.

anonymous
()
Ответ на: комментарий от xydo

>определение и реализация - разные вещи.
Позвольте поинтересоваться, чем разные?

Booster ★★
()
Ответ на: комментарий от kemm

>Спасибо, кэп! Я, какбэ, иллюстрировал неправоту утверждающих, что в C отсутствим объявления является ошибкой.
Не отсутствием объявления. А вызовом функции, которая не была до этого определена в данном модуле или объявлена. Но суть от этого принципиально не меняется, не стоит придираться. Или у вас другие сакральные знания?

Booster ★★
()
Ответ на: комментарий от Booster

> Не отсутствием объявления. А вызовом функции

Не вызовом, а любым использованием. Что подразумевается само собой.

Но суть от этого принципиально не меняется


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

не стоит придираться.


Из вас двоих пока придираешься только ты, провокационно-грубыми вопросами:

Или у вас другие сакральные знания?


,делая ошибки в формулировках, и не по теме. :3

LamerOk ★★★★★
()
Ответ на: комментарий от Booster

Ещё один, который считает, что отсутствие объявления функции до её вызова является ошибкой? В школу, учить С, строем по одному ШАГОМ А-А-А-АРШ!

kemm
()
Ответ на: комментарий от Zodd

Что такое «сама функция g()»? Читайте сначала топик хотя бы... Посмотрите, например, на какой комментарий я отвечал.

roof ★★
()
Ответ на: комментарий от kemm

У топикстартера про С не было ни слова. Это раз. Вызов функции, которая не объявлена в текущей области видимости, в С++ является ошибкой. Это два. И незачем так орать (С) :)

roof ★★
()
Ответ на: комментарий от LamerOk

>Из вас двоих пока придираешься только ты, провокационно-грубыми вопросами:

,делая ошибки в формулировках, и не по теме. :3

Я к вам не обращался вот и не встревайте.

Booster ★★
()
Ответ на: комментарий от kemm

>Ещё один, который считает, что отсутствие объявления функции до её вызова является ошибкой? В школу, учить С, строем по одному ШАГОМ А-А-А-АРШ!
Да считаю. В школе к сожалению такого не объясняют. Если вы считаете иначе, то будьте добры аргументируйте. Иначе демагогия.

Booster ★★
()
Ответ на: комментарий от roof

> У топикстартера про С не было ни слова. Это раз. Вызов функции, которая не объявлена в текущей области видимости, в С++ является ошибкой. Это два.

Тред надо читать, а не фантазировать про C++. Вот ключевое сообщение:

http://www.linux.org.ru/jump-message.jsp?msgid=4491306&cid=4492277

И незачем так орать (С) :)

Ну а что ещё с ними делать?.. 8))

kemm
()
Ответ на: комментарий от Booster

> Да считаю.

А зря.

В школе к сожалению такого не объясняют.

Найдите другую школу, что ли.. Эта плохая и негодная. 8))

Если вы считаете иначе, то будьте добры аргументируйте. Иначе демагогия.

Берём стандарт C и читаем. Либо берём компилятор C и пробуем, если стандарт читать лень.

kemm
()
Ответ на: комментарий от kemm

>Берём стандарт C и читаем. Либо берём компилятор C и пробуем, если стандарт читать лень.
Это вам нужно в школу, читать стандарт и пробовать.

Booster ★★
()
Ответ на: комментарий от Booster

Ещё из забавного, вдруг таки спогвигнет прочитать стандарт, прежде чем что-то там «считать»:

unknown();

int main()
{
    return unknown(17);
}

int unknown(int i)
{
    return i * 2;
}

Это корректная программа на C.

kemm
()
Ответ на: комментарий от kemm

Я просил аргументировать, а не разводить демагогию. Покажите где в стандарте это прописано?
Вот мой аргумент: http://lord-n.narod.ru/download/books/walla/programming/Spr_po_C/11/1118.htm
Если Вы мне не покажете, где в стандарте прописано, что компилятор обязан делать неявные объявления, то двоечник Вы.

Booster ★★
()
Ответ на: комментарий от Booster

> Покажите где в стандарте это прописано?

В C89, искать «implicit function declaration». Из C99 упоминание убрали, но именно что убрали, а не обязали считать ошибкой. Я не знаю ни одного компилятора, который считал бы использование необъявленной функции ошибкой в умолчальной конфигурации.

kemm
()
Ответ на: комментарий от kemm

И что с того что Вы не знаете такого компилятора? Язык не компилятор. С99 это стандарт и если не объявить функцию, то значит не придерживаться его. И не просто убрали упоминание, а именно убрали неявные объявления, писать так нельзя. В общем-то всё.

Booster ★★
()
Ответ на: комментарий от Booster

> И что с того что Вы не знаете такого компилятора? Язык не компилятор. С99 это стандарт и если не объявить функцию, то значит не придерживаться его.

Расскажи это разработчикам gcc, они будут рады. Ишь ты, стандарт нарушают, ироды, даже с '-std=c99 -pedantic' ошибкой не считают.

И не просто убрали упоминание, а именно убрали неявные объявления, писать так нельзя.

Убрали упоминание. Слов 'should not' я там не вижу. Это во-первых. Во-вторых и главных, «язык C» != «ISO/IEC 9899:1999». Фразы «согласно C99 вызов функции до её объявления может считаться ошибкой» и «отсутствие объявления функции в С является ошибкой» — две сильно разные фразы.

kemm
()
Ответ на: комментарий от kemm

>Фразы «согласно C99 вызов функции до её объявления может считаться ошибкой» и «отсутствие объявления функции в С является ошибкой» — две сильно разные фразы.
Для меня это означает запрет, в своем коде неявных объявлений я делать не буду. Как делать Вам, дело Ваше, но писать, что так можно делать это излишне самонадеянно и по-моему как минимум не корректно. Повторю компилятор это не язык, стандарт нам говорит не использовать больше неявных объявлений, и компилятор об этом предупреждает.

Booster ★★
()
Ответ на: комментарий от Booster

Я не говорю, что так надо делать, я говорю, что неявное объявление в С есть и оно не является ошибкой. Так тяжело читать, что написано, а не между строк вычитывать, чего там не было?

Чтобы понятнее было, пример: использование в printf(3) аргумента не того типа, что описан в строке формата, не является ошибкой в С. Но является фигнёй, допускать которую нельзя.

Повторю компилятор это не язык

Yep. Один стандарт — тоже не язык.

стандарт нам говорит не использовать больше неявных объявлений

Хде стандарт такое говорит? Если бы в природе не существовало C89 и K&R, то тогда ой, но они, увы, были.

PS: Я вообще большой поклонник явного и нелюбитель умолчаний, а так же считаю, что весь код должен собираться без предупреждений при указании '-Wall', чтобы два раза не вставать уж. А то любите приписывать какую-то фигню, которую я не говорил...

kemm
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.