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.
Related
This is a thought experiment.
This question is intentionally trying to do something easy in a difficult way. I am aware of the many ways to do this using iostream, std.h, etc. Please do not suggest answers that circumvent the challenge.
Using C++,
Only using main() without any header files included, is it possible to write a program that creates a variable of any type, and outputs the value of the variable in any way, such as printing it in console, saving it to a file, anything like that?
The goal is to have a .main file that looks like:
int main(){
Some code;
return 0;
}
I've tried using C's printf but that requires a header.
The best I could come up with is saving the value to a specific space in memory then using another program to read that block. But that is somewhat circumventing the goal of outputting only from main.
This may be impossible.
If you want to have no code outside of main, in C you could do this:
int main()
{
int puts(const char *);
puts("Sup!\n");
return 0;
}
Or the same thing with printf, or any other C standard library function.
It wouldn't work in C++ though, since in C++ the puts declaration needs extern "C" to disable name mangling, which can only be used outside of functions.
There's a trick that lets you do it in C++:
int main()
{
extern int puts;
((int(*)(const char *))&puts)("Sup!\n");
return 0;
}
Variable names are not mangled, so by tricking the compiler into thinking that puts is a variable rather than a function, you can get rid of the mangling without extern C.
Technically, this satisfies your constraints:
int main() {
return 123;
}
Most OSs allow you to check a program's return code. So this communicates one number to the outside world. The available range of values may differ with the OS.
You wrote "only main", but extern "C" cannot go into a block. So, if you can live with that line outside the main function, here's the code you asked for:
extern "C" int printf(const char *fmt, ...);
int main() {
printf("Hello %s\n", "world");
return 0;
}
Proof: https://godbolt.org/z/41WhGYc79
Perhaps I haven't understood correctly, but if you want to avoid the includes/libraries then the short answer is no. A C++ header (apart from templates) is just a declaration of a possible link-time function availability and you will always need them.
Almost anything meaningful you can do with C++ (as in any programming language, even assembly) requires a call to the underlying OS and this requires a header and a library link.
Even something as simple as a char output requires thousands of lines to communicate with a device driver to output to screen.
Even if you don't include anything, the compiler will inject code (CRT) that calls the OS by using a library no matter what. Even a simple main() requires lots of calls to the OS, for actually there is no "main" entry point in the executable.
That does not exactly answer your question, but if you were doing this in C rather than C++, then for most compilers that would be a valid program (without any includes):
int main()
{
printf("hello");
return 0;
}
Although it generates a warning.
Combining two of the answers above I was able to use printf by replacing the parts of
extern int puts;
((int(*)(const char *))&puts)("Sup!\n");
With parts that would allow printf:
extern int printf;
((int(*)(const char *fmt, ...))&printf)("%d\n", 10);
So the full code would be:
int main(){
int num = 10;
extern int printf;
((int(*)(const char *fmt, ...))&printf)("%d\n", num);
return 0;
}
I hope this helps, this is a combination of two responses not my own.
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.
Below c++ program works fine, even though i have not allocated any memory to chr.
I went through google, SO and came across this
Why does this intentionally incorrect use of strcpy not fail horribly?
Here the program works fine for destination which has space less than the source.
Does that apply in my case also,strcpy writes into a random location in the heap?
#include<iostream>
using namespace std;
class Mystring
{
char *chr;
int a;
public:
Mystring(){}
Mystring(char *str,int i);
void Display();
};
Mystring::Mystring(char *str, int i)
{
strcpy(chr,str);
a = i;
}
void Mystring::Display()
{
cout<<chr<<endl;
cout<<a<<endl;
}
int main()
{
Mystring a("Hello world",10);
a.Display();
return 0;
}
output:-
Hello world
10
I tried the same thing with another c++ program, with any class and class member, and i was able to see the crash.
#include<iostream>
using namespace std;
int main()
{
char *src = "Hello world";
char *dst;
strcpy(dst,src);
cout<<dst<<endl;
return 0;
}
Please help me understand the behavior in the first c++ program.Is memory allocated somehow or strcpy is writing to some random memory location.
The behavior of your program is undefined by the C++ standard.
This means that any C++ implementation (e.g. a compiler) can do whatever it wants. Printing "hello!" on stdout would be a possible outcome. Formatting the hard disk would still be acceptable, as far as the C++ standard is involved. Practically, though, some random memory on the heap will be overwritten, with unpredictable consequences.
Note that the program is even allowed to behave as expected. For now. Unless it's Friday. Or until you modify something completely unrelated. This is what happened in your case, and is one of the worst thing to happen from the point of view of a programmer.
Later on, you may add some code and see your program crash horribly, and think the problem lies in the code you just added. This can cause you to spend a long time debugging the wrong part of the code. If that ever happens, welcome to hell.
Because of this, you should never, ever, rely on undefined behavior.
strcpy() is indeed writing to a random location.
And it's a blind luck if your program runs fine and nothing crashes.
You have created on object of MyString class on a stack. In that object there's a member pointer chr, which points to some arbitrary location. Does your constructor take care to initialize that pointer or allocate a memory for the pointer to point at? -- No, it doesn't. So chr points somewhere.
strcpy() in its turn doesn't care about any pointer validity, it trusts your professionalism to provide valid input. So it does its job copying stings. Luckily, overwriting memory at the location pointed by an uninitialized chr doesn't crash you program, but that's "luckily" only.
It is known that strcpy() can cause overflow errors, because there is no check made wherever the data will fit in the new array or not.
The outcome of this overflow may sometime never been noticed, it all depends on where the data is written. However a common outcome is heap and/or program corruption.
A safe alternative of strcpy() is the usage of strcpy_s() that requires also the size of the array. You can read more about the usage of strcpy_s() on MSDN or here
Actually, strcpy() does something like this:
char *strcpy(char *dest, const char *src)
{
unsigned i;
for (i=0; src[i] != '\0'; ++i)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}
So, when you pass a pointer to some character array to strcpy, it copies data from src to dest until it reaches NULL terminated character.
Character pointer does not contain any information about length of string, so when you pass dest pointer, it copies data even though you haven't assigned memory to it.
Run this example code, you will get my point:
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char str1[] = "Hello_World!";
char str2[5];
char str3[10];
strcpy(str2,str1);
cout << "string 1:" << str1 << endl;
cout << "string 2:" << str2 << endl;
cout << "string 3:" << str3 << endl;
return 0;
}
This will not show any error but you can understand by my example that this is not a good practice.
Here is what my book says:
char *p="Hello"; //pointer is variable, string is constant
*p='M'; // error
p="bye"; // works
Well, in C my second line does not give me any error, Neither in C++.
I am using Turbo C++ on windows 7. Now is the above thing true if i try in gcc or something else.
Also on the similar lines if the above code is correctly interpreted by the book,
#include<iostream.h>
void display(char*);
void display(const char*);
void main()
{
char* ch1="hello";
const char *ch2="bye";
display(ch1);
display(ch2);
}
void display(char* p)
{
cout << p << endl;
}
void display(const char* p)
{
cout << p << endl;
}
Now is my book considering char* and const char* the same because if it is then the above code shall not work, since arguments will be the same?
(Though i get the output Hello bye on turbo +windows.)
Which one is correct?
The language specification is not a promise that compilers make to you, but a mutual contract that you and compilers both sign onto. (Metaphorically speaking, of course. Obviously it's not a literally legally binding contract.) If you violate the contract by writing *p='M';, then you've triggered "undefined behavior", and you can't expect any specific behavior from the compiler: maybe it will be strict about it and give you a compile error, maybe it will just go wonky at run-time . . . you didn't hold up your end of the bargain, and it's allowed to do literally whatever it wants now. See also: http://catb.org/jargon/html/N/nasal-demons.html.
Question:
“Now is my book considering char* and const char* the same because if it is then the above code shall not work, since arguments will be the same?”
Well you’re probably misrepresenting your book.
It probably does not consider those types to be the same, because they are not the same.
Now to your code:
#include<iostream.h>
[iostream.h] is not part of standard C++. C++ was standardized in 1998, and that standardization dispensed with the ARM era's [iostream.h]. So a modern compiler will likely choke on that.
As a workaround, when you get yourself a less antique compiler, you might do …
#include <iostream>
using namespace std;
Next,
void display(char*);
void display(const char*);
Declaring functions at the top of the file generally just yields extra work. It often means maintaining two declarations of the function. When you could have dealt with just one declaration.
void main()
In standard C and standard C++ main is not allowed to have any other result type than int.
Visual C++ is one compiler that, as a language extension, permits void.
However, it’s quite silly to use that possibility since it is more to write and just makes the code non-standard and likely to not compile with other compilers.
{
char* ch1="hello";
By C++11 rules the above will not compile. It was deprecated in C++98 and removed in C++11. However, AFAIK current compilers still allow it, but some have a warning that can be turned on.
const char *ch2="bye";
display(ch1);
display(ch2);
}
The above is OK, although it would not hurt to add an extra const, like
const char* const ch2="bye";
char* ch1="hello";
is deprecated in C++. The correct way is const char*. Because "hello" is stored in a read only region. Also, int main() or int main(int, char**) is the correct way of defining main().
Don't use Turbo C, it's an outdated compiler. Go for gcc or MSVC. Also, don't use books which provides such incorrect information.
char *p="Hello"; //pointer is variable, string is constant
This code is allowed, because it has been valid since long before the C language got a const keyword.
In order not to break old code, the C and C++ standards just documented that this should work like before.
However, if you write new code you should use the proper form const char*.
I am trying to play fancy games which have the C++ compiler synthesize hash values of constant strings at compiletime. This would let me replace the string with a single identifier, with a massive savings in code size and complexity.
For programming clarity and ease, it'd be awesome if I could examine and compute at compiletime with simple inline character strings like "Hello" which are compiletime constant pointers to compiletime constant chars.
If I can index into these at compiletime, I can make a template metaprogram to do what I want. But it is unclear if the C++ standard treats a ct-constant index of a ct-constant array as ct-constant by itself.
Asked another way,
const char v="Hello"[0];
is quite valid C++ (and C). But is the value v a compile time constant?
I already believe the answer is no, but in practice some compilers accept it without even any warning, much less error. For example, the following compiles and runs without even a single warning from Intel's C++ compiler:
#include <iostream>
const char value="Hello"[0];
template<char c> void printMe()
{
std::cout << "Template Val=" << c << std::endl;
}
int main()
{
const char v='H';
printMe<'H'>();
printMe<v>();
printMe<value>(); // The tricky and interesting case!
}
However, Microsoft's compiler will not compile at all, giving a reasonably coherent error message about using a template with an object with internal linkage.
I suspect the answer to my question is "No, you can't assume any array reference even to a constant array with a constant index is constant at compiletime". Does this mean the Intel compiler's successful execution is a bug in the Intel compiler?
It doesn't work on GCC either.
However, outside of a language-compliance viewpoint, it's nice that the compiler optimiser does treat it as a character constant, pretty much. I exploited that fact to allow preprocessor-generated character constants (by using *#foo). See http://cvs.openbsd.org/cgi-bin/query-pr-wrapper?full=yes&numbers=1652, in file hdr.h. With that macro, you could write
DECR(h, e, l, l, o)
rather than
DECR('h', 'e', 'l', 'l', 'o')
Much more readable, in my view. :-)
Good question, yes this can be done, and its fine with the standards, and it'll work on Microsoft, GCC, and Intel, problem is you have the syntax wrong :)
One second I'll cook up a sample...
Ok done, here it is. This sample is valid C++, and I've used it quite often, but indeed most programmers don't know how to get it right.
template<char* MSG>
class PrintMe
{
public:
void operator()()
{
printf(MSG);
}
};
char MyMessage[6] = "Hello"; //you can't use a char*, but a char array is statically safe and determined at compiletime
int main(int argc, char* argv[])
{
PrintMe<MyMessage> printer;
printer();
return 0;
}
The relevant difference here is the difference between a "Integral Constant Expression" and a mere compile-time constant. "3.0" is a compile-time constant. "int(3.0)" is a compile-time constant, too. But only "3" is an ICE. [See 5.19]
More details at boost.org