True Function Type?

Hello all,

I have to admit,the cplusplus website is definitely the site to hang out at ;)

I'm new to c++ and currently enrolled in courses and absolutely having a blast learning this magnificent language however I ran into a little snag and I was hoping someone would be willing to clarify a situation I ran into in the course.

The problem I am having is the instructor keeps talking about 'localizing' functions and I don't really understand this. Unless I'm just not getting it.

The code he uses to demostrate as a properly declared and defined "local" function is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include <iostream>

using namespace std;

int main() {


void customFunct() {

       cout <<" print something... " << endl;
}

return 0;
}


Now, when I try to copy this, I receive the following error even though all code blocks are properly closed:


error: a function-definition is not allowed here before the '{' token.


Even though the compiler keeps spitting it out, I'm still told by the instructor that it is valid code and there's something wrong with my code. Now the code you see above is the exact same code the instructor is using that I'm trying to copy and I don't understand how I'm doing something wrong.

As far as I understand it, and tried to reason with too no prevail, the function definitions cannot exist within the main() because it's considered 'nesting' and is illegal in c++. Or am I just making some learner's mistake? The following code snippet is what I believe is required by C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#include <iostream>

using namespace std;

// declare and define function.
void customFunct() {

       cout <<" print something... " << endl;
}

int main() {


     customFunct();

return 0;
}


OR the following if you wish to use functions with other functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

#include <iostream>

using namespace std;

// declare function.

void customFunctA();
void customFunctB();

int main() {

     customFunctB();

return 0;
}

// create function definitions

void customFunctA() {
     cout <<" Inside customFunctA but called through customFunctB. " <<endl;
   }
void customFunctB() {
     customFunctA();
  }


Now am I wrong about anything or am I just not seeing what the instructor is trying to teach me?

Thanks in advance for all your help.
Sorry to say this, but your instructor is really a ...

You are absolutely right, definitions of functions can't be local.
Hi Danielsson,

Thanks for your help, it's very much appreciated.

Going back to functions, is there ever a time the function can "not" work out side of it's scope? Or is a function 100% global the whole time?

Thanks for the help.
as long as you have included the file in which you have the function you can use it.
There is no such thing as a "local" function in C++.

What you ought to do is take that code snippit that he gave you over to the chair of your computer science department and demand a teacher who knows C++ to teach you C++. Not all computer languages are the same.


There exist namespaces designed to scope functions. Notice how the standard library is all in the std namespace.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <cctype>
#include <iostream>
#include <string>

namespace wolfcry
  {
  std::string titlecase( const std::string& s )
    {
    if (s.empty()) return s;

    std::string result( s );
    for (unsigned n = 1; n < result.length(); n++)
      result[ n ] = std::tolower( result[ n ] );
    result[ 0 ] = std::toupper( result[ 0 ] );

    return result;
    }

  std::string greeting()
    {
    return titlecase( "hello world!" );
    }

  } // namespace wolfcry

int main()
  {
  std::cout << wolfcry::greeting() << std::endl;
  return 0;
  }

Line 5 starts a new "namespace" or naming scope for things like functions and types and the like.

Inside that namespace you have two functions: titlecase() and greeting(). Both are visible outside the namespace, but only explicitly. Hence, line 28 must use wolfcry:: to indicate where the greeting() function is found. It could just as easily been written like:

1
2
3
4
5
6
int main()
  {
  using namespace wolfcry;
  std::cout << greeting() << std::endl;
  return 0;
  }


However, inside the local namespace, you can refer to other functions local to that namespace without an explicit prefix, as on line 21.

Notice that throughout we still had to refer to the std namespace explicitly. As usual, we can avoid that (and for good measure, we'll use an alternate way to get at something in the wolfcry namespace):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <cctype>
#include <iostream>
#include <string>
using namespace std;

namespace wolfcry
  {
  string titlecase( const string& s )
    {
    if (s.empty()) return s;

    string result( s );
    for (unsigned n = 1; n < result.length(); n++)
      result[ n ] = tolower( result[ n ] );
    result[ 0 ] = toupper( result[ 0 ] );

    return result;
    }

  string greeting()
    {
    return titlecase( "hello world!" );
    }

  } // namespace wolfcry

int main()
  {
  using wolfcry::greeting;
  cout << greeting() << endl;
  return 0;
  }

Hope this helps.
Duoas wrote:
What you ought to do is take that code snippit that he gave you over to the chair of your computer science department and demand a teacher who knows C++ to teach you C++. Not all computer languages are the same.


I agree with Duoas. If your instructor is clueless on such a basic concept... in my opinion you cannot trust what he teaches and need a new instructor.

@chimera: Thank you chimera for pointing that out. I never thought of that. That does make sense though. If the definition isn't included in another file, that file wouldn't know what to do with it.

@Return 0: I'm definitely going to take yours and duoas advice in regards to speaking to the higher ups, but I want to talk to the instructor again though because maybe he was just seeing his code wrong thinking it was outside of main() at the bottom. Maybe he didn't realize main's last curly brace was after the function. But then again, I'd have to ask why didn't he declare the function before main() if he was trying to define it at the bottom. We all make mistakes and it could just be human error but if he still insists that he's right and I'm wrong even after showing him, then I'm moving out of his 'scope' lol. Thank you for your help.

@Duoas: Thank you very much for your clarification of the scope of functions it definitely shined some light. If I'm understanding you correctly, the "scope" of a function isn't really dealing with if it's a global or not within a file (because functions are always global) but the "scope" of how it's called correct? With that said, why go through the extra effort to call a function using a new namespace, if the end result is the same thing as if you just used the regular namespace (using namespace std;), by itself. And without having to write more code just to call the function? Is it standard practice to do this? Or am I off here?

I understand that your function is "contained" in the new namespace and must be explicitly called to work using the namespace name and the scope resolution operator, but I'm having difficulty understanding the purpose for doing this and please excuse my ignorance.. C++ is not that easy to wrap the mind around.

Thanks again for all of your help guys. It is very much appreciated and definitely needed.
Last edited on
Namespaces were created to deal with exactly that problem: everything in C appears in the global context. The problem is that while there are gadzillions of possible identifiers to choose from, it is unlikely that ones like zyxctl_arbuf will be used by anyone. Hence, you have potential collisions.

C++ inherited the problem, but chose to deal with it by giving identifiers a lexical scope. This is kind of like a full name. I know a Julie Wilson[1] at work, and a Julie Anderson at church. Unless they are both present, I just call the one who is with me 'Julie'.

Namespaces work the same way. If you need to, you can always refer to an entity by its full name:
std::cout, wolfcry::greeting(), etc.

However, you can also say that you are only interested in a specific collection of names:
using namespace std;, using wolfcry::greeting;, etc. Thereafter whenever you say "cin" or "greeting" the compiler knows which item you are referring to -- even if an identically named item exists in another namespace.


For beginning homework assignments and the like namespaces aren't that big a deal. When you get into industry code or public libraries, it becomes very important: you will always want to put your stuff into a namespace and prevent collisions between libraries and any other user code.

Hope this helps.

[1] Names have been wholly created for your edification, and to protect the innocent.
Last edited on
Hi Duoas,

Oh ok, so this is how the encapsulation comes into play. I never truly understood that concept until now. It makes perfect sense though, because if I had a program that used the function redApples(); and my source is integrated with another program say, a program that categorizes apples with the same function name of redAppples();, the two will most likely collide and crash the program.

So by encapsulating, the program is 'safe' and I / or someone else won't have to rewrite my code just to integrate it with another program that may or may not use the same function name.

Am I on the right track with my analogy?

Also, just to update those who first helped me in regards to the instructor. Basically, when he realized the code was bad he tried to say that I 'modified' the original code even though the supposedly 'modified ' code was what he handed out and was teaching. Some people lol.
closed account (S6k9GNh0)
I think we should celebrate that someone is actually asking us questions about C++ instead of their homework.

1) If you have multiple definitions of a function within scope of a prototype or call, the compiler will (or should) error out and tell you what is wrong and where. I mentioned this since you said the program would crash, which means that it would run at all which isn't true since it will not compile.

2) I can picture the provided bad code from your instructor being a typo or something similar to.

3) Namespaces have many uses.
1) Name scheming. Instead of cqWindow, it can be as obscure and take advantage of namespaces with cq::Window
2) To prevent function collision. Say your using multiple audio decoding libraries. Each one has a class called Decode. When you compile your code that creates an instance of the class Decode, how would the compiler magically be able to tell which Decode class you meant? It doesn't and to prevent this, the libraries will place their classes inside of a namespace.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
namespace ogg
{

class Decode
{
   public:
      Decode()
};

}

namespace lame
{

class Decode
{
public:
   Decode();
};

}

using namespace lame; //We will use the lame namespace.

int main()
{
   Decode *decoder = new Decode; //The ogg namespace is completely ignored and is out of our scope.
   lame::Decode * anotherDecoder = new lame::Decode; //We explicitly move into lames namespace. 
   delete decoder;
   delete anotherDecoder;
}


In all of reality, namespace could be completely removed from the picture with a name scheme containing the prefix which would have been the name of your namespace, e.g. oggDecode or lameDecode. Namespaces however provides extensive features and is considered clean and wanted in standard C++.
Last edited on

1) If you have multiple definitions of a function within scope of a prototype or call, the compiler will (or should) error out and tell you what is wrong and where. I mentioned this since you said the program would crash, which means that it would run at all which isn't true since it will not compile.

2) I can picture the provided bad code from your instructor being a typo or something similar to.


Hi computerquip and thank you for your help. I definitely need all the help I can get. In my opinion learning is half the fun and the other half is trying to make sense of what I just learned lol.

In regards to #1: Excellent point. I guess if a program was to 'crash' it would do more with stuff like not validating user input such as requiring integers but the user can input characters.

For #2: I suspect(ed) the same thing and that's why I wanted to talk to him before doing anything because I didn't want to cause problems, I even would've been happy if he responded by saying it was a test to see if I would catch it, however, when shown the error and instead of taking some responsibilty he tries to pass the buck of blame. I have to admit, that didn't sit well with me lol. I love learning C++, I love how you all have been extremely patient and helpful with me and I love this site, so I'm going to keep coming back here to supplement my learning, but I just hope I can find an instructor I can actually trust to be actually teaching me proper code. Because now, I'm going to have to double check all of what he's teaching me and that's not cool.

Ok, I believe I got a grasp on this and that was an excellent example. How do you know what code structure to use? Not just code related to namespaces but code in general. I'm finding that C++ allows you, basically, a million different ways to achieve the same result so how do you know what is proper and what isn't? Reading numerous posts on this site, I'm constantly seeing things such (And please don't ask for actual threads because right now, I can't remember lol) as "don't do that, it's not proper", or "why did you write it that way, when you could've just..." etc etc.? Isn't the way something is coded pretty much programmer preference?

For Example:
Being a Chef, I know that you can take a few ingredients and make a basic pancake properly, but there's still a million different ways to make that same pancake using different ingredients, cooking techniques, personal preferences / tastes etc. And depending on the breakfast 'type', which ingredients to use and not to use, which are proper and which are not etc. I hope this is making sense but it's the best analogy I can come up.

Again, thanks to all of you! You've all been a huge help!
Last edited on
Glad to have been of help.

Unfortunately for the beginner, C++ is a multi-paradigm language, meaning that there are a gadzillion ways to do a thing.

Even among those, however, there is kosher and simple, and there is dangerous and overworked.

:-)
also, most of the times that people say that you shouldn't do that is because it isn't c++ standard, and try to prevent that new programmers get a bad habit with for example using System("pause") when that only works with windows, just an example ;)
@Duoas: multi-paradigm is an understatement lol.

@chimera: That's understandable. It's always better to not get messed up with bad habits from the get-go. Just makes life a whole lot easier down the road. Just like guitar playing lol.


Thanks a bunch guys!

See you around the forum.
Topic archived. No new replies allowed.