Uninitialized constant, compilation error, C++, GNU - c++

I've just learned what a constant is in C++ and tried the following code on Code::Blocks and it gives me the following compile-time errors:
error: uninitialized constant 'b'[-fpermisive]
and
no match for operator >>
(I am using namespace std).
My guess is that uninitialised constants are not allowed in C++. Why is this so?
Note: I am learning to code for the first so, I will be glad if you can explain it without referring any other language.
const int b;
cin >> b;

Constants have to be initialised when they are declared, after they have been declared they cannot be changed.
If you want to store your value that you are reading from the console in a const the simplest way is probably to do so via a function:
int readInt()
{
int i;
std::cin >> i;
return i;
}
int main()
{
const int b = readInt();
}

Related

error: lvalue required as increment operand without an error line

I've seen a similar post on StackOverflow about this error code, but theirs seemed to have an error code line, and they were also attempting something slightly different in their function.
I'm trying to count the number of a specified character in a string (inputting p and apple would return 2, for example). At some point, my method broke down. I've been scouring my code for what specific increment operator is causing this, but without an error code line I don't know which one is causing it, and I've messed around with both.
I'm not sure which of these variables isn't modifiable, but all it tells me is:
main.cpp:11:30: error: lvalue required as increment operand
If anyone could take a look at my code and tell me what's wrong, I would really appreciate it.
#include <iostream>
#include <string>
using namespace std;
int main() {
string b;
char a;
int i;
int counter(string b) {
counter = 0;
for(int i = 0; i < b.length(); i++)
if (b[a] == a), counter++);
counter = i;
return counter;
}
cin >> a;
cin >> b;
return counter(b);
}
return 0;
}
PS, I know this code has multiple other errors. It's a work in progress, but I am trying to focus on this operand issue first.
I've been trying to redefine variables for both counter and i, as I'm not sure which one is causing the issue, but nothing has fixed it. For example, within the for loop, I tried setting counter equal to some variable, but that didn't help. I think it's possible I messed up the syntax too within the for loop, and I spent some time in there, but if that's the issue I didn't fix it.
The program is invalid
In this line
int counter(string b); {
^^^
you declared a function with the name counter (see the semicolon).
After the function declaration there is followed a compound statement
int counter(string b); {
counter = 0;
for(int i = 0; i < b.length(); i++)
if (b[a] == a), `counter++`);
return counter;
}
within which the function name counter is used as a variable as for example counter++
So the compiler issues the error message
"main.cpp:11:30: error: lvalue required as increment operand".
because you are using the function name and trying to apply to it the post-increment operator ++. But the function designator in this case in implicitly converted to a pointer to the function and it is not an lavlue.
After the compound statement you are calling the function counter though it is not defined
return counter(b);
It seems you are trying to define the function counter within the function main. You may not do that.
Also the function should accept two arguments: the string and the character.
Your program can look the following way
#include <iostream>
#include <string>
size_t counter( const std::string &s, char c )
{
size_t count = 0;
for ( char ch : s )
{
if ( c == ch ) ++count;
}
return count;
}
int main()
{
std::string s;
char c;
std::cin >> s;
std::cin >> c;
std::cout << counter( s, c ) << '\n';
}

return struct value in C++

When I studied const reference type in C++,
I learned returning reference type make use local variable in main function,
so I tested how returned normal struct type work in lvalue. so I expected this source won't compile,
but it compiled well... :(
so I have two question
"Is returned struct variable?, why this code compiled well?"
"if returned struct is not variable, why this code compiled?, I assumed that returned value is rvalue.."
#include<iostream>
#include<cstring>
using namespace std;
struct travel_time
{
int hour;
int min;
};
travel_time sumTime(travel_time, travel_time);
int main(void)
{
travel_time p1, p2,sum;
cin >> p1.hour >> p1.min;
cin >> p2.hour >> p2.min;
sum=sumTime(p1, p2);
cout << sum.hour << "hour " << sum.min<<"min";
sumTime(p1, p2) = p1; //********** why it works? **********
return 0;
}
travel_time sumTime(travel_time t1, travel_time t2)
{
travel_time sum;
sum.hour = t1.hour + t2.hour+(t1.min+t2.min)/60;
sum.min = (t1.min + t2.min) % 60;
return sum;
}
Is returned struct variable?, why this code compiled well?
This doesn't make much sense.
travel_time sum; is a variable. When you call sumTime, you return a copy of this variable, and that copy itself isn't a variable. So the answer is no, the result of calling the function isn't a variable.
I have a feeling what you really wanted to ask is if the result of calling the function is an lvalue - it's not, the result is an rvalue (more specifically, prvalue).
if returned struct is not variable, why this code compiled?, I assumed that returned value is rvalue..
This again makes no sense, unless I replace "variable" with "lvalue".
In C++, you can assign to rvalues of class types (but not of privitive types such as int). Note that struct travel_time is a class, despite using the word "struct". Strictly speaking, there are no structures in C++, only classes.
There are ways to prevent this kind of assignment for your class, but you didn't do that.

C++: Built-in arrays

I thought that built-in arrays in C++ are statically allocated. But the following code works:
//...
int x;
std::cin >> x;
const int cx = x;
int array[cx];
//...
Why does it?
Variable length arrays are not part of the C++ standard, however your compiler allows it. If you use the -pedantic-errors option with your compiler (assuming g++), this will throw an error as that option strictly enforces the standard.

why does this code show segmentation fault?

#include"iostream"
using namespace std;
class xxx
{
public:
char **a;
xxx();
~xxx();
};
xxx :: xxx()
{
a=new char*;
*a="10";
cout<<endl<<*a; // works fine
cout<<"Enter name:";
cin>>*a; // segmentation fault??
}
xxx :: ~xxx()
{
delete a;
}
main()
{
xxx x;
cout<<*x.a;
}
why can't I change the name field using cin ?
When i am calling a constructor it is assigning the value to the variable but While editing it is showing the following error:
program has stopped working.
same problem arises for method.What am I missing.
Within the constructor of xxx, *a is initialised so it points at (the first character of) a string literal.
The statement cin >> *a then attempts to modify the string literal. That gives undefined behaviour. The symptom you are describing is one possible outcome of undefined behaviour.
A simpler example, without the obfuscating details of class xxx would be
#include <iostream>
int main()
{
char **a = new char *;
*a = "10";
std::cout << std::endl << *a; // works fine
std::cout << "Enter name:";
std::cin >> *a; // undefined behaviour here
}
Although, as with any form of undefined behaviour, a particular outcome/symptom is not guaranteed.
You might try turning up warning levels for your compiler, and the result will probably be warnings about a suspicious conversion in the statement *a = "10" (e.g. converting something const to not const). Most modern C++ compilers (and quite a few older ones) are configured to NOT warn about such things by default, but can be configured to issue such warnings. Turning up compiler warnings, and taking heed of them, is helpful in reducing such types of undefined behaviour.
The problem with your code is quite simple, for that matter. In your constructor:
xxx :: xxx()
{
a=new char*;
*a="10";
cout<<endl<<*a; // works fine
cout<<"Enter name:";
cin>>*a; // segmentation fault??
}
You are trying to read into an already initialized string literal, which is then causing Undefined Behavior. If you want to do something like this, and you are using C++, you should probably switch to std::string, which will make your code a lot simpler without dealing with raw string literals and pointers, as follows:
#include <iostream>
#include <string>
class xxx
{
public:
std::string a;
xxx();
~xxx();
};
xxx :: xxx()
{
a = "10";
std::cout << std::endl << a;
std::cout << "Enter name:";
std::cin >> a;
}
int main()
{
xxx x;
std::cout<< x.a;
}
In this example, code such as a=new char*; and delete a; are removed along with the destructor itself. Other changes I made include changing your code to not using using namespace std; (Read why it is considered bad practice) and using the return type of int for main(). Additionally, I included the <string> library as well for std::string. Finally, as another recommendation, since std::cin will only read the first word passed to it and ignore the rest, if you want to read a full name then you can use getline() as follows:
//std::cin >> a; becomes...
getline(std::cin, a);
Issue in your code can be minimized to this snippet of invalid code:
char *p = "foobar"; // should not compile, but would on many compilers due to backward compatibility
p[0] = 'F';
issue is you are trying to modify memory where string literal resides which is UB.

Passing a variable into an initialization of an array as a reference in a function parameter

I've been trying to learn C++ recently, and doing some hacker rank introductory tasks. I am attempting to do the https://www.hackerrank.com/challenges/deque-stl challenge, but I am very unfamiliar with c++ syntax and uses of their base "array". If I would prefer, I would at the very least use std::array (although I understand that is nothing but a zero overhead wrapper of the default C array).
My problem is this:
#include <iostream>
#include <deque>
#include <vector>
#include <array>
#include <typeinfo>
using namespace std;
void printKMax(int (&arr)[n], int n, int k){
//Write your code here.
deque<int> d(arr);
cout << arr[3];
for(int i:d) {cout <<i;}
}
int main(){
int t;
cin >> t;
while(t>0) {
int n,k;
cin >> n >> k;
int i;
int arr[n];
for(i=0;i<n;i++)
cin >> arr[i];
printKMax(arr,n, k);
t--;
}
return 0;
}
I am trying to pass the arr into printKMax, and receive it as a reference.
The error I am receiving is:
!‘arr’ was not declared in this scope
!‘n’ was not declared in this scope
!variable or field ‘printKMax’ declared void
!expected primary-expression before ‘int’
!expected primary-expression before ‘int’
of which if I use a constant int, eg "5", arr[5], it passes through.(passing arr[5] in the function call too). But if I replace with n, it doesn't work.
That is, at the moment, it is printKMax(arr,n,k) at the function call [not the definition], and I see no reason to add the arr[n] here (as it is already implicit in the array it is declared as: int arr[n]). I am trying to pass it as a reference, without it decaying into a pointer. I have messed around with passing it as *arr too, but with no success.
I read online its important to keep it as (&arr)[100] or something along those lines, but here I have (&arr)[n], and it is out of scope. I would love to just write (&arr)[], but alas I get this error instead:
parameter ‘arr’ includes reference to array of unknown bound ‘int []’
Thanks in advance! Also, is this only a problem with arrays? If I start using and and such data structures from eg the boost library, will I encounter similar problems?
PS: ignore the deque code, I was just playing around, trying to initialise it with the same elements as the array I am passing. It is probably incompatible since one is std:: and the other is default array unfortunately...?