Expected unqualified-id before 'xor' token - c++

Why the g++ compiler says: error: expected unqualified-id before 'xor' token
class BigInteger{
public:
unsigned *array;
BigInteger xor(BigInteger bi){ // g++ indicates error this line
BigInteger n;
if(bi.array == (unsigned*)0){
return n;
}
return n;
}
};

xor is an alternative token for ^ in C++, you can't use it as an identifier. Same for or/bitor and and/bitand (||, |, && and & respectively), and a few others. They are essentially keywords like if or for.
Choose a different name for your function.
Full list of alternative tokens (C++ standard §2.12 Keywords, see §2.6 Alternative tokens for the mappings):
and
and_eq
bitand
bitor
compl
not
not_eq
or
or_eq
xor
xor_eq

Groan. Yes, this very thing is one of those chase-your-tail and then realize "What?" and shake your head situations.
In my case similar, I have a class definition, which defines a class method:
List* xor(List* list)
And one gets the g++ useful error message of:
error: expected unqualified-id before ‘^’ token
Eventually one finds that xor is a synonym for ^ and as such cannot be a function name.
What makes it worse (in my case) is that this works perfectly FINE in MS Windows under Visual Studio (2010 in my case). And is code that has been under development through various Visual Studio versions since 1999 (Visual Studio 6).
So now I need to rename the function and rebuild on Windows as well as g++ on linux... one of those problems that gets bigger as you work on it.

Related

Permitted usage context of declarations

The following code
#include <iostream>
#include <memory>
#include <ios>
using std::cout;
using std::endl;
using std::unique_ptr;
using std::make_unique;
using std::boolalpha;
template<typename T>
struct alloc{
alloc();
unique_ptr<T> operator() (void){
return(auto up = make_unique<T>(NULL));
}
};
int main (void){
auto up = alloc<int>()();
cout << boolalpha << ((up) ? 1 : 0) << endl;
return 0;
}
when compiled gives the following error:
g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra -c code.cpp
code.cpp: In member function ‘std::unique_ptr<_Tp> alloc<T>::operator()()’:
code.cpp:14:16: error: expected primary-expression before ‘auto’
return(auto up = make_unique<T>(NULL));
^~~~
code.cpp:14:16: error: expected ‘)’ before ‘auto’
make: *** [makefile:20: code.o] Error 1
There is an earlier question on SO reporting the same error:
C++17 std::optional error: expected primary-expression before 'auto'
The following is a snippet from the accepted answer to the above question:
Declarations are not expressions. There are places where expressions
are allowed, but declararions are not.
So my questions based on the compilation error I get are:
a) Is the use of a declaration in a return statement not permitted by the standard?
b) What are the permitted contexts for declarations?
Note: I had deliberately used the auto keyword in the return statement to reproduce this error. This error had originally appeared in a larger code base.
TIA
Is the use of a declaration in a return statement not permitted by the standard?
Indeed it isn't. We need only examine the grammar production at [stmt.jump]/1
Jump statements unconditionally transfer control.
jump-statement:
break ;
continue ;
return expr-or-braced-init-listopt ;
goto identifier ;
There is no production that turns an "expr-or-braced-init-list" into any sort of statement, so no declaration statement either. There is also no production that turns it into any other sort of declaration (such as a function, namespace or class). So you cannot declare anything in the return statement's operand.
What are the permitted contexts for declarations?
Almost anywhere an expression isn't required explicitly. The very definition of a translation unit in C++ (one file being translated) is a sequence of declarations per [basic.link]/1.
A program consists of one or more translation units linked together. A
translation unit consists of a sequence of declarations.
translation-unit:
declaration-seqopt
Different declarations have different structure. Somes such as namespaces, may contain more declarations. Others such as functions may contain statements, which themselves may be declaration statements of certain things. But most importantly, the standard makes clear where a statement may appear, and where only an expression is permitted.

Capitalize first letter of string

I am trying to capitalize the first character of a std::string, using the same method mentioned here. For example for the following program
#include <cctype>
#include <iostream>
#include <string>
int main()
{
std::string name = "foobar";
name[0] = std::toupper(name[0]);
std::cout << name;
}
I am expecting the output to be
Foobar
When I compile this online (using GCC 4.9.2) I get the correct output without any warnings. However, when I compile the same code in Visual Studio 2013, I get a warning during the assignment back from toupper
warning C4244: '=' : conversion from 'int' to 'char', possible loss of data
Is the above method valid according to the C++ standard or is the warning correct? Otherwise is this just a false warning by Visual Studio?
The warning is correct as far the types go; the type of std::toupper as defined in the standard is:
int toupper( int ch );
Mostly because it's a remnant from the dark C ages (the cctype header is a hint at that).
However, this is just a part of the story. There's another toupper residing in the locale header:
template< class charT >
charT toupper( charT ch, const locale& loc );
This one shouldn't give you any warnings. If you're not sure what locale to provide, std::locale() will give you the default one.
std::toupper comes from the C standard, not C++, and has an annoying interface in that it takes and returns an int not a char. Using static_cast<char>(std::toupper(name[0])) will suit you.
The warning is correct, compiler will implicitly cast from int to char but this might cause lost of data in some cases. To see warning under gcc you need to add -Wconversion compiler option. Which will generate:
main.cpp: In function 'int main()':
main.cpp:8:13: warning: conversion to '__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type {aka char}' from 'int' may alter its value [-Wconversion]
name[0] = std::toupper(name[0]);
^
Foobar
Why it is not present when -Wall is set, read here:
https://gcc.gnu.org/wiki/NewWconversion
Why isn't Wconversion enabled by -Wall or at least by -Wextra?
Implicit conversions are very common in C. This tied with the fact
that there is no data-flow in front-ends (see next question) results
in hard to avoid warnings for perfectly working and valid code.
Wconversion is designed for a niche of uses (security audits, porting
32 bit code to 64 bit, etc.) where the programmer is willing to accept
and workaround invalid warnings. Therefore, it shouldn't be enabled if
it is not explicitly requested.

Program without semicolon compiles fine in C not in C++ why?

I am using Orwell Dev C++ IDE. Recently I tested following simple program in which I forgot to put semicolon (;) but still it compiles fine in C but not in C++. Why? What is the reason?
// C program compiles & runs fine, even ; missing at end of struct
#include <stdio.h>
struct test
{ int a,b}; // missing semicolon
int main()
{
struct test d={3,6};
printf("%d",d.a);
return 0;
}
[Warning] no semicolon at end of struct or union [enabled by default]
// Following is compilation error in C++
#include <stdio.h>
struct test
{ int a,b}; // missing semicolon
int main()
{
struct test d={3,6};
printf("%d",d.a);
return 0;
}
[Error] expected ';' at end of member declaration
I also tried same C program in codeblocks 13.12 IDE but it shows following error message
error: no semicolon at end of struct or union.
Why different error messages given by different implementations?
The semicolon is required by both languages. Specifically, C specifies the declaration of one or more structure members as
struct-declaration:
specifier-qualifier-list struct-declarator-list ;
and C++ specifies the declaration of one or more class member variables as
member-declaration:
attribute-specifier-seq<opt> decl-specifier-seq<opt> member-declarator-list<opt> ;
both of which require a semicolon at the end.
You'll have to ask the compiler writers why their C++ compiler is more strict than their C compiler. Note that the language specifications only require a "diagnostic" if a program is ill-formed, so it's legitimate either to issue a warning and continue compiling as if the semicolon were present, or to issue an error and stop.
It looks like your IDE is using GCC as its compiler; in which case you could use -Werror to convert warnings into errors, if you'd prefer stricter diagnostics.

How to compare two std::istream references?

I am switching over compilers from GCC to Clang/LLVM and running into compilation errors I didn't experience before.
I have a class that looks something like this:
#include <iostream>
class foo {
public:
bar(std::istream& is) : _fp(is), _sCheck(is != std::cin) { /* ... */ }
private:
std::istream& _fp;
bool _sCheck;
}
When I compile this file, I get the following error with clang++, where the initialization of the private variable _sCheck fails:
error: invalid operands to binary expression ('std::istream' (aka
'basic_istream<char>') and 'istream' (aka 'basic_istream<char>'))
(is != std::cin)
~~ ^ ~~~~~~~~
If both objects in this address comparison are of the same type, why is clang++ returning an error, while g++ does not?
I tried a dynamic_cast to make them both std::istream&, but this, too, returned an error:
error: invalid operands to binary expression ('std::istream' (aka
'basic_istream<char>') and 'std::istream')
(is != dynamic_cast<std::istream&>(std::cin))
~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I apologize in advance if this is a dumb question; I appreciate any pointers.
You are using references, so you are comparing the objects and not the pointers as you maybe intended to. It seems GCC has an extension which allows you to compare std::istream objects, but this is not part of the standardized interface of std::basic_istream. Try:
_sCheck(&is != &std::cin)

what does this C++ line of code mean "sol<?=f((1<<n)-1,i,0)+abs(P[i])*price;"

Could anyone help me to understand following line of code:
sol< ?=f((1<< n)-1,i,0)+abs(P[i])*price;
I am studying an algorithm written using c++ and it has following operator < ?= . My problem is with understanding < ?= operator. Also when I compile this code using g++ compiler , it gives error message for above line of code line of code
following is the error message returned.
Hello.cpp: In function ‘int main()’:
Hello.cpp:115: error: ‘memset’ was not declared in this scope
Hello.cpp:142: error: expected primary-expression before ‘?’ token
Hello.cpp:142: error: expected primary-expression before ‘=’ token
Hello.cpp:142: error: expected ‘:’ before ‘;’ token
Hello.cpp:142: error: expected primary-expression before ‘;’ token
Maybe < ?= it is not a single operator, but I can not understand what exactly this line of code does.
Thanks in advance for the time you spent reading this post.
It's a GNU extension. It's basically a "lower than" operator.
int a = 3;
a <?= 2;
cout << a << endl; // prints 2, because 2 < 3
a <?= 10;
cout << a << endl; // prints 2 as well, because 10 > 2
Read more here.
To be clear for anyone reading this and not being able to follow; <?= and >?= are assignment versions of <? and >? which are deprecated GCC extensions which served the purpose of (x>y)?x:y or (x<y)?x:y respectively.
Therefore, x <?= y; would be x = x <? y; which is x = (x<y) ? x : y;
Most compiler vendors introduce language extensions, and many make it into future language standards. Usually these extensions are either just very easy to add or make the job of writing standard libraries much easier.
It could almost be a line of PHP code though: all it needs is remove a space to form at the end.
<?= foo(); ?>
is equivalent to
<?php echo foo(); ?>
Take a look at the C grammar here
The only use of ? is in the ternary operator:
conditional_expression
: logical_or_expression
| logical_or_expression '?' expression ':' conditional_expression
;
Where the ? is followed by an expression. This does not happen in your case. So your code is not a valid C.
This line isn't a line of code. That's why it doesn't compile. It is meaningless to ask what it does.