const char* vs char* - c++

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*.

Related

Can you output data in C++ without using any includes?

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.

What rules of C++11 standard are used to determine the type of the expression in ({ ... })

I hasn't understand what compiler does here and why it's working c++ code
#include <cstdio>
int main()
{
printf( ({ // (1)
struct some_noize_struct {
// there may be another code
};
42;
"abc";
}) // (2)
);
return 0;
}
Type of expression between (1) and (2) braces is const char*. After some experimens i unrerstood that type of (1)-(2)-expression determined by last part.
Here is a sample code. It works on c++11 and later.
http://cpp.sh/5tb47
My question: how it works.
As #HolyBlackCat explains, the code you listed uses a GCC compiler extension to C++ (and to C), while allows for compounds statements to be used as expressions.
In your printf() statement, you need to provide a const char* or const char* & expression as the first argument to the function, e.g. printf("hello") or printf(getenv("PATH")). The extension allows the interpretation of a curly-braced block as such an expression, using the last statement in the block. The block in your case is:
{
struct some_noize_struct { 42 };
42;
"abc";
}
which has 3 statements. The last statement is the value of the entire expression, which means that what the printf() sees is essentially the same as if you had typed printf("abc").
This kind of code is not standard C++ (C++11 or any another version), nor is it standard C.
I suggest you write the maintainers of the "C++ Shell" website and ask them to display the exact compilation command-line they use, and/or make sure they use --std=c++11 to compile C++11 code - which it looks like they aren't doing.

modify string by passing address in c++

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.

Why are (member) function pointers behaving so weirdly in Visual C++?

I've had a really bizarre problem that I've reduced to the following test case:
#include <iostream>
#include <map>
#include <string>
struct Test
{
std::map<std::string, void (Test::*)()> m;
Test()
{
this->m["test1"] = &Test::test1;
this->m["test2"] = &Test::test2;
}
void test1() { }
void test2() { }
void dispatch(std::string s)
{
if (this->m.at(s) == &Test::test1)
{ std::cout << "test1 will be called..." << std::endl; }
else if (this->m.at(s) == &Test::test2)
{ std::cout << "test2 will be called..." << std::endl; }
(this->*this->m.at(s))();
}
};
int main()
{
Test t;
t.dispatch("test1");
t.dispatch("test2");
}
It outputs
test1 will be called...
test1 will be called...
when optimizations are enabled, which is really bizarre. What's going on?
This is a by-product of what Visual C++ refers to as Identical COMDAT Folding (ICF). It merges identical functions into a single instance. You can disable it by adding the following switch to the linker commandline: /OPT:NOICF (from the Visual Studio UI it is found under Properties->Linker->Optimization->Enable COMDAT Folding)
You can find details at the MSDN article here: /OPT (Optimizations)
The switch is a linker-stage switch, which means you won't be able to enable it just for a specific module or a specific region of code (such as __pragma( optimize() ) which is available for compiler-stage optimization).
In general, however, it is considered poor practice to rely on either function pointers or literal string pointers (const char*) for testing uniqueness. String folding is widely implemented by almost all C/C++ compilers. Function folding is only available on Visual C++ at this time, though increased widespread use of template<> meta-programming has increased requests for this feature to be added to gcc and clang toolchains.
Edit: Starting with binutils 2.19, the included gold linker supposedly also supports ICF, though I have been unable to verify it on my local Ubuntu 12.10 install.
It turns out Visual C++'s linker can merge functions with identical definitions into one.
Whether that's legal or not according to C++, I have no idea; it affects observable behavior, so it looks like a bug to me. Someone else with more information may want to chime in on that though.
C++11 5.3.1 describes what & does; in this instance, it gives you a pointer to the member function in question, and the passage makes no requirement that this pointer must be unique.
However, 5.10/1 says about ==:
Two pointers of the same type compare equal if and only if they are both null, both point to the same function, or both represent the same address.
The question then becomes... are test1 and test2 "the same function"?
Though the optimizer has collapsed them into a single definition, arguably the two names identify two functions and, as such, this would seem to be an implementation bug.
(Note, though, that the VS team don't care and consider it "valid enough" to warrant the benefits of the optimisation. That, or they don't realise that it's invalid.)
I'd stick to using the strings as "handles" for your function pointers.

Is a compiletime constant index into a compiletime constant array itself compiletime constant?

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