I'm new to Sycl/DPC++ language. I wrote a sample vector addition code using Unified shared memory (USM):
#include<CL/sycl.hpp>
#include<iostream>
#include<chrono>
using namespace sycl;
int main()
{
int n=100;
int i;
queue q{ };
range<1>(n);
int *a=malloc_shared<int>(n,q);
int *b=malloc_shared<int>(n,q);
int *c=malloc_shared<int>(n,q);
for(i=0;i<n;i++)
{
a[i]=i;
b[i]=n-i;
}
q.parallel_for(n,[=](auto &i){
c[i]=a[i]+b[i];
}).wait();
for(i=0;i<n;i++){
std::cout<<c[i]<<std::endl;
}
free(a,q);
free(b,q);
free(c,q);
return 0;
}
When I compile it I get the following error:
warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'n' [-Wvexing-parse]
range<1>(n);
^~~
vec_add.cpp:11:1: note: add enclosing parentheses to perform a function-style cast
range<1>(n);
^
( )
vec_add.cpp:11:9: note: remove parentheses to silence this warning
range<1>(n);
^ ~
vec_add.cpp:11:10: error: redefinition of 'n' with a different type: 'range<1>' vs 'int'
range<1>(n);
^
vec_add.cpp:8:5: note: previous definition is here
int n=100;
^
1 warning and 1 error generated.
How to fix this error?
error: redefinition of 'n' with a different type: 'range<1>' vs 'int'
Two variables with the same name within the same scope create confusion to the compiler, so it might be the reason for the error which you are getting. You can try defining the value of n globally say for eg: #define N 100 in this case, set
range<1>(n);
to
range<1> (N);
and use that in your code.
If you want to declare the size locally then assign another variable (r) to the range as
range<1> r (n);
Now you can directly pass the 'r' variable as a parameter to the parallel_for.
Related
I'd like to doctest some conversion expression with C++ doctest.
I'm using a code similar to the following
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
TEST_CASE("operator int()") {
CHECK_THROWS_AS(int(2), std::invalid_argument);
int i;
CHECK_THROWS_AS(i = int(2), std::invalid_argument);
}
However in both case I get a warning:
dd.cpp:7:7: warning: variable 'i' set but not used [-Wunused-but-set-variable]
int i;
^
dd.cpp:6:19: warning: expression result unused [-Wunused-value]
CHECK_THROWS_AS(int(2), std::invalid_argument);
^ ~
How do I silence the warning in proper C++ (not using a particular compiler feature).
By the way, in my real code, 2 is actually replaced by an object of a class whose int operator may throw.
UPDATE:
Thanks to everyone for the help to understand this!
I try to run this:
#include <iostream>
int* x = new int;
*x = 5;
int main()
{
}
and i get the following errors:
1>------ Build started: Project: learnCpp, Configuration: Debug Win32 ------
1>learnCpp.cpp
1>C:\Users\Danie\source\repos\learnCpp\learnCpp.cpp(4,6): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Users\Danie\source\repos\learnCpp\learnCpp.cpp(4,2): error C2374: 'x': redefinition; multiple initialization
1>C:\Users\Danie\source\repos\learnCpp\learnCpp.cpp(3): message : see declaration of 'x'
1>C:\Users\Danie\source\repos\learnCpp\learnCpp.cpp(4,7): error C2440: 'initializing': cannot convert from 'int' to 'int *'
1>C:\Users\Danie\source\repos\learnCpp\learnCpp.cpp(4,4): message : Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>Done building project "learnCpp.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
however I don't get any errors if I assign the value to x inside the main function.
Like so:
#include <iostream>
int* x = new int;
int main()
{
*x = 5;
}
How come?
In the file scope in C you may place only declarations. You may not execute statements in the file scope. The same is valid for C++ where you may place in a namespace only declarations.
Note: In C declarations are not statements while in C++ declarations are statements. Nevertheless except the declaration statement other statements may not be present in a namespace in C++. It is interesting also to note that in C there is a null statement but there is no an empty declaration. While in C++ there may be an empty declaration.
So this program
#include <iostream>
int* x = new int;
*x = 5;
int main()
{
}
is invalid.
These error messages of the compiler
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2374: 'x': redefinition; multiple initialization
message : see declaration of 'x'
mean that the compiler tries to interpret the assignment statement as a declaration.
But this program
#include <iostream>
int* x = new int;
int main()
{
*x = 5;
}
is correct. In this program the assignment statement is present in the outer block scope of the function main.
What you are trying to do is not possible in global scope.
If you need to do this way try to initialize as below :
// good practice
namespace
{
int* x = new int(5);
}
int main()
{
// You can later modify in function scope
*x = 10;
}
You cannot have statements other than declarations, outside of any scope (for simplicity consider a scope whatever is inside brackets). So, compiler is trying to interpret
*x = 5;
as a declaration, so as a pointer to a given type, but does not find the type pointed to, so generates an error.
I was trying to implement mergesort in cpp. However, the Dev-cpp 5.6.1 reports some "not in this scope" error. It said, "lo", "mid", and "hi" was not declared in this scope. Can you tell me why this happens? Thanks.
#include<iostream>
using namespace std;
void merge(int nums[], int lo, int mid, int hi) {
int n1 = mid - lo + 1;
int n2 = hi - mid + 1;
/*Other implementation code omitted*/
}
int main() {
/*code to Input numbers into nums[]*/
merge(nums, 0, 4, 9);
return 0;
}
When reading error messages that involve syntax errors, it is important to pay the most attention to the very first one. This is because the C++ compiler is not obligated to stop at the first error, and more errors may be produced as a consequence of the first.
In your original code, you have a syntax error in your declaration of the nums parameter to your merge() function:
#include<iostream>
using namespace std;
int nums[10];
void merge(int[] &nums, int lo, int mid, int hi) {
int n1 = mid - lo + 1;
int n2 = hi - mid + 1;
/*Other implementation code omitted*/
}
int main() {
/*code to Input numbers into nums[]*/
merge(nums, 0, 4, 9);
}
You have since edited your program to remove that syntax error, but with this original code, I see the following error messages:
x.cc:3: error: expected ',' or '...' before '&' token
x.cc: In function 'void merge(int*)':
x.cc:4: error: 'mid' was not declared in this scope
x.cc:4: error: 'lo' was not declared in this scope
x.cc:5: error: 'hi' was not declared in this scope
x.cc: In function 'int main()':
x.cc:3: error: too many arguments to function 'void merge(int*)'
x.cc:11: error: at this point in file
You reported the was not declared in this scope errors, but failed to mention the first one, which is pointing out the syntax error for nums. Because of this syntax error, the compiler failed to parse the rest of the function parameters, so it reported those identifiers as having no visible declaration.
Fixing this error removes the others. This is because the parser for the function prototype now picks up the rest of the function arguments, so those are now in scope for the rest of the function.
Can someone please explain below output:
#include <iostream>
using namespace std;
namespace A{
int x=1;
int z=2;
}
namespace B{
int y=3;
int z=4;
}
void doSomethingWith(int i) throw()
{
cout << i ;
}
void sample() throw()
{
using namespace A;
using namespace B;
doSomethingWith(x);
doSomethingWith(y);
doSomethingWith(z);
}
int main ()
{
sample();
return 0;
}
Output:
$ g++ -Wall TestCPP.cpp -o TestCPP
TestCPP.cpp: In function `void sample()':
TestCPP.cpp:26: error: `z' undeclared (first use this function)
TestCPP.cpp:26: error: (Each undeclared identifier is reported only once for each function it appears in.)
I have another error:
error: reference to 'z' is ambiguous
Which is pretty clear for me: z exists in both namespaces, and compiler don't know, which one should be used. Do you know? Resolve it by specifying namespace, for example:
doSomethingWith(A::z);
using keyword is used to
shortcut the names so you do not need to type things like std::cout
to typedef with templates(c++11), i.e. template<typename T> using VT = std::vector<T>;
In your situation, namespace is used to prevent name pollution, which means two functions/variables accidently shared the same name. If you use the two using together, this will led to ambiguous z. My g++ 4.8.1 reported the error:
abc.cpp: In function ‘void sample()’:
abc.cpp:26:21: error: reference to ‘z’ is ambiguous
doSomethingWith(z);
^
abc.cpp:12:5: note: candidates are: int B::z
int z=4;
^
abc.cpp:7:5: note: int A::z
int z=2;
^
which is expected. I am unsure which gnu compiler you are using, but this is an predictable error.
You get a suboptimal message. A better implementation would still flag error, but say 'z is ambiguous' as that is the problem rather than 'undeclared'.
At the point name z hits multiple things: A::z and B::z, and the rule is that the implementation must not just pick one of them. You must use qualification to resolve the issue.
I am trying to cin a loop index's value in the loop itself using lambda expression:
#include<iostream>
using namespace std;
int main(){
for(int a, ([](int & b){cin>>b;})(a); a < 2; ++a);
return 0;
}
These are the errors when i compile using g++ 4.5 on ubuntu:
forLoopAndCinTest.c++: In function ‘int main()’:
forLoopAndCinTest.c++:5:14: error: expected unqualified-id before ‘[’ token
forLoopAndCinTest.c++:5:14: error: expected ‘)’ before ‘[’ token
forLoopAndCinTest.c++:5:34: error: expected primary-expression before ‘)’ token
forLoopAndCinTest.c++:5:34: error: expected ‘;’ before ‘)’ token
forLoopAndCinTest.c++:5:40: error: name lookup of ‘a’ changed for ISO ‘for’ scoping
forLoopAndCinTest.c++:5:40: note: (if you use ‘-fpermissive’ G++ will accept your code)
forLoopAndCinTest.c++:5:50: error: expected ‘;’ before ‘)’ token
If i use a normal function instead of the lambda, program compiles fine.
Using -fpermissive doesnt help either.
Any ideas?
That's not how the for look works. You are trying to call a lambda where the compiler expects you to declare an int:
for( int a, int2, ...; a < 2; ++a );
Now,
If i use a normal function instead of
the lambda, program compiles fine
Yes, but it's probably not doing what you think it does.
void f(int& b)
{
cin >> b;
}
// ...
for( int a, f(a); a < 2; ++a );
Here, the loop declares two int variables, named a and f. The loop doesn't call f() as you might expect.
Try this instead:
for( int a; cin >> a && a < 2; ++a );
The first part of the for is interpreted as a declaration. We get the very same error when replacing your code by the (almost) equivalent :
int main(){
int a, ([](int & b){cin>>b;})(a); // This produces the same error
for(; a < 2; ++a);
return 0;
}
To answer a comment you made, for (int a, foo() ; ... works, but not like you think it does. It is in fact declaring a function (inside the for scope) that returns an int, and has the name foo. As in :
int a, foo();
Which you should read as :
int a;
int foo();
After this: for( int a, compiler expects some name (of the variable) - unqualified-id.
But in your case it is not so.