Consider this simple program:
#include <iostream>
void length(void){
std::cout<<"My length is void"<<std::endl;
}
void width(void){
std::cout<<"My width is void"<<std::endl;
}
int main(void){
std::cout<<"The program length is: "<<length<<std::endl;
std::cout<<"The program width is: "<<width<<std::endl;
}
The output of this program is:
The program length is: 1
The program width is: 1
What are the numbers that the program prints out, and basically not having much knowledge in C++ particularly, this looks more pythonic syntax to me,and looks as if it should print the function address. I say this because, this problem arose initially while practicing some very basic programs for openGL,
The callback was registered in GLUT with something like:
void line(void){
//some code for line program ...
}
int main(int argc, char** argv){
//some more code;
glutDisplayFunc(line);
glutMainLoop();
}
It's almost seeming as if we're passing the address of the function, but, clearly from the above program this is not an address, and the syntax for pointer to function is a bit different, if so, how is this function being registered for callback? And what is it that we're passing to glutDisplayFunc?
and, since I **wanted to register a function that had passed arguments, I search a C++ analogy for python lambda functions, and found similar lambda function, but it didn't work out: **
#include <iostream>
void line(int a, int b){
//some code that does some plotting in the display window
}
int main(int argc, char** argv){
auto callback = [](void)->void{
line(a,b);
};
glutDisplayFunc(callback);
glutMainLoop();
}
This totally fails,the error that is shown is:
no suitable conversion function from "lambda []void ()->void" to "void (*)()" exists
This was using my python analogy, but what's the solution to this problem? The major parts of confusion are highlighted in bold.
It's almost seeming as if we're passing the address of the function, but, clearly from the above program this is not an address
You've got things backwards. It's not glutDisplayFunc that's doing the weird magical thing; it's std::cout.
Yes, a function name will convert to a function pointer. The combination of operator<< overloads for iostreams and C++ overload resolution rules ultimately leads to << treating functions as if they were boolean values (yes, really). And thus, your << length is equivalent to doing << true.
If you want the address, you can cast the function pointer to a void* before outputting it: << reinterpret_cast<void*>(&length) or the more terse << (void*)&length (though technically this is only conditionally supported by C++, pretty much every real compiler will allow this).
Lastly, in C++, lambdas are not functions; they're objects. You cannot pass an object to something that expects a function pointer. You can convert a capture-less lambda into a function pointer, but you can't do that for one which captures values.
Related
I am reading The C++ Programming Language by Bjarne Stroustrup. It states an example to explain function-pointers:
int cmp1(const void∗ p, const void∗ q) // Compare name strings
{
return strcmp(static_cast<const User∗>(p)−>name,static_cast<const User∗>(q)−>name);
}
Then it uses this cmp1 in ssort, something like this:
int main()
{
cout << "Heads in alphabetical order:\n";
ssort(heads,6,sizeof(User),cmp1);
print_id(heads);
//Rest of function body
}
My question is: is &cmp1 being passed as an argument in ssort() because we can't pass a function as an argument, we can only pass a function-pointer?
My question is: is &cmp1 being passed as an argument in ssort() because we can't pass a function as an argument, we can only pass a function-pointer?
Your code does not use &cmp1. Hence, your question does not match your code.
Still, a function can be passed without using the addressof operator (&).
ssort(heads, 6, sizeof(User), &cmp1);
is the same as
ssort(heads, 6, sizeof(User), cmp1);
Functions decay to function pointers in this context.
A functions name indeed represent the starting address of the executable code for the function. So it's more like the arrays where its name can be used as pointer to the array itself. Also go through
https://www.geeksforgeeks.org/function-pointer-in-c/
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
How does the main() function handle a variable number of arguments without the use of ellipses (...)? For processing variable number of arguments, last argument to the function should be ... which is not the case with the main() function.
Basically, main() is special, and it has two standard-defined forms:
int main(int argc, char **argv)
int main(void)
The system may support other forms; it is common that the environment is also made available:
int main(int argc, char **argv, char **envp)
These forms are fixed. The only unusual thing is that a system must support either of the first two (and some systems support others as well).
The variable number of command line arguments is handled via an array of pointers to strings (that's argv above), unlike say execl() from POSIX.
See also:
How does the main() function in C work?
What should main() return in C and C++?
rahul manglani commented:
The two links you mentioned made it pretty clear. There are different possible approaches listed there, which of them is actually being used is not mentioned.
In a sense, it doesn't matter; the system simply has to work, and the people who produce 'the system' must make it work. You as the programmer using the system don't need to know how it works; you can simply assume that it does work.
Behind the scenes, what usually happens is that the 'start' function which calls main() does some fixup work (in the case of a C++ program in particular, a lot of fixup work — such as ensuring all the constructors that must be executed before main() starts are in fact executed), but ends with a fixed sequence such as:
exit(main(argc, argv, environ));
Note that environ is a global variable, extern char **environ; (which is unique among the global variables defined by POSIX in that no header declares it) and it contains the pointers to the environment variables. The 'start' code has to ensure that is set; it is trivial to pass environ as an argument to main(), therefore.
This calls main() with a fixed argument list and calls exit() if/when it returns. Indeed, Apple takes it a step further and passes a fourth argument to main(). If the called function was defined as int main(void) { … }, it simply ignores the arguments it was passed; if it was defined as int main(int argc, char **argv) { … }, it can access the command line arguments as usual; if it was defined as int main(int argc, char **argv, char **envp) { … }, then it can access the environment too.
Generally, the systems are set up so that extra arguments don't cause damage. This is a reason why C is unusual in its calling conventions and it's why the called function doesn't clean up the arguments pushed onto the stack — the called function doesn't know how many arguments were actually pushed onto the stack. It assumes that the ones it expects were provided and uses those without problems, but the calling code knows what it pushed so it can clean up properly. The biggest problems occur if the called function expects N arguments but the caller passes M arguments and M < N. (There are also issues of types pushed and the sizes of those types, etc, but that's a second-order problem.)
In C/C++ main takes 2 parameters, typically called argc, and argv. The argv parameter is an array of argc char arrays. Command line arguments are passed to the program in argv. There are variations on this theme with the exact number of parameters, but main's signature is generally
int main(int argc, char **argv);
I interpreted this question to mean: how is it possible that main can take either zero arguments or two arguments?
While the details are obviously implementation-dependent, on most implementations, the default C calling convention is that the caller cleans the stack. Therefore, the code that calls main is at perfect liberty to always push two arguments onto the stack (argc and argv), whatever the declaration of main might be. If main is declared with no arguments, then main simply won't access the values of the arguments it receives. After main returns, the calling code clears the stack.
It should be pointed out that main isn't even special in this sense. Try this:
int printf();
int main() { printf("Hello, world!\n"); }
The C compiler will happily allow you to call printf even though, lacking an #include <stdio.h> directive, it has no idea how many arguments printf actually wants. Presumably, the code that calls main is conceptually something like this:
int main(int argc, char** argv); /* declare "main" */
main(argc, argv); /* call "main" */
If the definition of main actually specifies zero parameters, this still works (although I believe it would technically be undefined behaviour if you actually did this).
In the case of C++, although the linkage of main is left unspecified by the standard, most implementations simply treat it as though it has C linkage, so the name is not mangled and everything above still applies.
It handles it by accepting an array and array length set as variables argc and argv
you may find more data here:
http://crasseux.com/books/ctutorial/argc-and-argv.html
I am working on a piece of structured programming homework that requires that I make a program that allows the user to enter names blah blah blah and so on. What I want to do after putting names into the string array is to print them to the screen. I had hoped to accomplish this by passing the array and the number of names contained therein to a function that would then print them to the screen. I wanted to pass the array and number of names as constants so that it would safeguard them so they couldn't be modified by the function, just read-only. I don't understand why I can't put const before the string array or the number of names though.
void writeNames (const string namelist[], const int number_of_names)
Is this something I just have to accept or is there a way I can pass both of those as read-only to the function? I can complete the homework without this so this is more a question of curiousity than a "help me with my homework" one.
P.S. Vectors seem to be a way of doing a lot more things with strings and such, but we haven't got to them in class yet and therefore I can't use them yet either.
Thanks
Without seeing what you're doing within the function, it's hard to answer the question, but my crystal ball says that you're probably doing something that could potentially modify one of the parameters within your method, so the compiler is complaining because you declared the parameter const.
As an example, something like this works just fine:
void writeNames(const std::string namelist[], const int number_of_names)
{
for(int i = 0; i < number_of_names; i++) {
std::cout << namelist[i] << std::endl;
}
}
However, something like this would cause a compiler error, since you're changing one of the variables:
void writeNames(const std::string namelist[], const int number_of_names)
{
while(number_of_names--) { // <-- We're modifying a const value here
std::cout << namelist[count] << std::endl;
}
}
Incidentally, putting the const modifier on your "number_of_names" parameter is somewhat redundant since you're passing the parameter by value, so changing the value within the function would have no effect on the value of the input parameter in the calling function. A change in any of the strings in the array, however, would be reflected in the calling function, so the const modifier there makes sense. Generally you would use const only on parameters that are either pointers, or being passed in by reference.
I want to modify the string variable present in main function by the external function, by passing the address of the same.
Below is the code which I've written
void change(char * str)
{
str="Max";
}
void main()
{
char a[]="Test";
change(a);
cout<<a;
}
Please correct me if I am wrong
Please note that I am using Borland Turbo C++ 4.5.
I guess you mean pass by reference, you can simply pass the given string by reference to the external function as follows:
void modifyString( string& str)
{
//modify the string
}
inside main, you can call this function.
You want this:
void change(char * str)
{
strcpy(str,"Max");
}
Recall what a pointer is, and that the pointer itself cannot be changed only what it points to.
First of all you should not use Turbo C/C++, It was last updated long time ago,
You can change a string in a function as follows,
void change(char * str)
{
*(str+0)='M';
*(str+1)='A';
*(str+2)='X';
*(str+3)='\0';
}
int main()
{
char a[]="Hello";
change(a) ;
}
You ask,
“correct me if i am wrong”
after presenting this code:
void change(char * str)
{
str="Max";
}
void main() {
char a[]="Test";
change(a);
cout<<a;
}
So, here goes:
str="Max";
only changes the local pointer str. with a compiler conforming to the C++11 standard it won’t even compile, because str is declared as char* while the literal "Max" is of type char const [4], and C++11 does not anymore support an implicit conversion from string literal to pointer to non-const.
void main
will not compile with any standard-conforming C or C++ compiler, no matter which standard. however, visual c++ will compile it with no diagnostic. and possibly old turbo c++ did too, but note that turbo c++ predated the first C++ standard (which came in 1998). the standard requires int result type for main for an ordinary hosted C++ implementation.
cout<<a;
will not compile with a standard-conforming compiler without including <iostream> and having a using declaration or directive. note that this changed with the standardization. before the 1998 standard, in ARM C++, you could include <iostream.h> and use unqualified cout.
A proper way to do your program, in modern C++, is
#include <iostream> // std::cout, std::endl
#include <string> // std::string
using namespace std;
string foo() { return "Max"; }
int main()
{
string a = "Test";
a = foo(); // Changed!
cout << a << endl;
}
another answer, which as I’m writing this you have selected as “solution”, recommends using raw pointers and strcpy, instead of std::string. using raw pointers and arrays is advice that will make you unhappy if you follow it. for example, it’s very easy to inadvertently write beyond the end of the provided buffer, with disastrous effects. ownership handling is exceedingly difficult to do correctly, and so on. the advice was presumably given in the Stack Overflow tradition of answering the literal question with no regard for what the question was really about, which is a good way to obtain Stack Overflow reputation points (it beats me what is so desirable about them, the silly T-shirts or whatever are really not worth it), at the cost of creating severe problems for others, sort of like maiming a few bystanders in order to steal a small bar of chocolate.
This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 9 years ago.
Does it matter which way I declare the main function in a C++ (or C) program?
The difference is one is the correct way to define main, and the other is not.
And yes, it does matter. Either
int main(int argc, char** argv)
or
int main()
are the proper definition of your main per the C++ spec.
void main(int argc, char** argv)
is not and was, IIRC, a perversity that came with older Microsoft's C++ compilers.
https://isocpp.org/wiki/faq/newbie#main-returns-int
Bjarne Stroustrup made this quite clear:
The definition void main() is not and never has been C++, nor has it even been C.
See reference.
You should use int main. Both the C and C++ standards specify that main should return a value.
For C++, only int is allowed. For C, C99 says only int is allowed. The prior standard allowed for a void return.
In short, always int.
The point is, C programs (and C++ the same) always (should?) return a success value or error code, so they should be declared that way.
A long time ago I found this page (void main(void)) which contained many reasons outside of the "the standard says it is not valid" argument. On particular operating systems/architectures it could cause the stack to become corrupted and or other nasty things to happen.
If you're going by the spec, then you should always declare main returning an int.
In reality, though, most compilers will let you get away with either one, so the real difference is if you want / need to return a value to the shell.
In C++, main() must return int. However, C99 allows main() to have a non-int return type. Here is the excerpt from the C99 standard.
5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent; or in some other implementation-defined manner.
Also note that gcc does compile void main() although practically, it does a return 0; on encountering a closing brace.