Does g++ contain the functional library? - g++

I have problems with using functional in g++. I compile with !g++ -o test test.cpp -std=c++11 and it does not give any errors and the program also runs fine. I use Syntastic to check any errors before compiling, and it gives me the following output.
This is my program test.cpp:
1 #include <functional>
2
3 using namespace std;
4
5 int f(int x){
6 return x;
7 }
8
9 void f2(function<int(int)> f){
10
11 }
12
13 int main(){
14 return 0;
15 }
The error is:
1 test.cpp|9 col 9 error| variable or field ‘f2’ declared void
2 test.cpp|9 col 9 error| ‘function’ was not declared in this scope
3 test.cpp|9 col 18 error| expected primary-expression before ‘int’
What does this error mean and how do I fix it?

The problem was that Syntastic was not checking c++11 code since functional can only be used with c++11. That was the reason the compiling went fine and the output file displayed correct results.
I found the answer in this question after discovering the root of the problem:
how to add c++11 support to syntastic vim plugin?
so I just had to add
let g:syntastic_cpp_compiler_options = ' -std=c++11 -stdlib=libc++'
to my vimrc

Related

incomplete type `std::string' when building OSDK on Raspberry Pi 4

I am trying to build the DJI Onboard-SDK on a Raspberry Pi 4, and have had errors with different libraries missing that I have managed to resolve by installing those libraries. I've now gotten an error saying std::string isan incomplete type and printf is not declared. The only suggestions I've found say to install build-essentials, which I've already got installed and up to date. Can anyone give me suggestions about where to look next?
I've tried reinstalling g++ and ensuring all packages are up to date. I'm still getting the following errors in my make output;
[ 26%] Building CXX object osdk-core/CMakeFiles/djiosdk-core.dir/modules/src/filemgr/impl/mmap_file_buffer.cpp.o
In file included from /home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/src/filemgr/impl/mmap_file_buffer.cpp:4:
/home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/inc/filemgr/impl/mmap_file_buffer.hpp:23:15: error: field ‘currentLogFilePath’ has incomplete type ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’}
23 | std::string currentLogFilePath;
| ^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/iosfwd:39,
from /usr/include/c++/10/memory:74,
from /home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/inc/filemgr/impl/mmap_file_buffer.hpp:13,
from /home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/src/filemgr/impl/mmap_file_buffer.cpp:4:
/usr/include/c++/10/bits/stringfwd.h:74:11: note: declaration of ‘std::string’ {aka ‘class std::__cxx11::basic_string<char>’}
74 | class basic_string;
| ^~~~~~~~~~~~
/home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/src/filemgr/impl/mmap_file_buffer.cpp:15:39: error: ‘path’ has incomplete type
15 | bool MmapFileBuffer::init(std::string path, uint64_t fileSize) {
| ~~~~~~~~~~~~^~~~
In file included from /usr/include/c++/10/iosfwd:39,
from /usr/include/c++/10/memory:74,
from /home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/inc/filemgr/impl/mmap_file_buffer.hpp:13,
from /home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/src/filemgr/impl/mmap_file_buffer.cpp:4:
/usr/include/c++/10/bits/stringfwd.h:74:11: note: declaration of ‘std::string’ {aka ‘class std::__cxx11::basic_string<char>’}
74 | class basic_string;
| ^~~~~~~~~~~~
/home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/src/filemgr/impl/mmap_file_buffer.cpp: In member function ‘bool DJI::OSDK::MmapFileBuffer::init(std::string, uint64_t)’:
/home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/src/filemgr/impl/mmap_file_buffer.cpp:19:3: error: ‘printf’ was not declared in this scope
19 | printf("Preparing File : %s\n", this->currentLogFilePath.c_str());
| ^~~~~~
/home/pi/catkin_ws/src/Onboard-SDK/osdk-core/modules/src/filemgr/impl/mmap_file_buffer.cpp:7:1: note: ‘printf’ is defined in header ‘<cstdio>’; did you forget to ‘#include <cstdio>’?
6 | #include <string.h>
+++ |+#include <cstdio>
7 |
make[2]: *** [osdk-core/CMakeFiles/djiosdk-core.dir/build.make:524: osdk-core/CMakeFiles/djiosdk-core.dir/modules/src/filemgr/impl/mmap_file_buffer.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:580: osdk-core/CMakeFiles/djiosdk-core.dir/all] Error 2
make: *** [Makefile:149: all] Error 2

Export COMMON block from DLL with gfortran

I am having trouble correctly accessing a variable in a Fortran DLL from a Fortran EXE when the variable is part of a COMMON block.
I have a trivial code simple.f90 which I compile into a DLL using MSYS64/MinGW-w64 gfortran 9.2 as
x86_64-w64-mingw32-gfortran simple.f90 -o simple.dll -shared
! simple.f90
module m
implicit none
integer :: a, b
!common /numbers/ a, b
end module
subroutine init_vals
use m
implicit none
a = 1
b = 2
end subroutine
This library is used from a even simpler program prog.f90, compiled as
x86_64-w64-mingw32-gfortran prog.f90 -o prog -L. -lsimple
! prog.90
program p
use m
implicit none
print *, 'Before', a, b
call init_vals
print *, 'After', a, b
end program
When the COMMON block /numbers/ is commented out, the code works and prints the expected result:
Before 0 0
After 1 2
However, when I uncomment the COMMON block, the output becomes
Before 0 0
After 0 0
as if the variables used by the program were suddenly distinct from those used in the library.
Both variants work equally well in a Linux-based OS with gfortran 9.1.
I am aware that "On some systems, procedures and global variables (module variables and COMMON blocks) need special handling to be accessible when they are in a shared library," as mentioned here: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gfortran/GNU-Fortran-Compiler-Directives.html . However, I was not able to insert a statement of the type
!GCC$ ATTRIBUTES DLLIMPORT :: numbers
or
!GCC$ ATTRIBUTES DLLEXPORT :: numbers
anywhere in the code without being snapped at by the compiler.
As pointed out by M. Chinoune in the comment, current gfortran lacks the ability to import common blocks from DLLs. Even though there has been a patch for some time, it is not yet merged. In the end, I needed two things to make the above code work:
First, apply the following patch to GCC 9.2 and compile the compiler manually in MSYS2:
--- gcc/fortran/trans-common.c.org 2019-03-11 14:58:44.000000000 +0100
+++ gcc/fortran/trans-common.c 2019-09-26 08:31:16.243405900 +0200
## -102,6 +102,7 ##
#include "trans.h"
#include "stringpool.h"
#include "fold-const.h"
+#include "attribs.h"
#include "stor-layout.h"
#include "varasm.h"
#include "trans-types.h"
## -423,6 +424,9 ##
/* If there is no backend_decl for the common block, build it. */
if (decl == NULL_TREE)
{
+ unsigned id;
+ tree attribute, attributes;
+
if (com->is_bind_c == 1 && com->binding_label)
decl = build_decl (input_location, VAR_DECL, identifier, union_type);
else
## -454,6 +458,23 ##
gfc_set_decl_location (decl, &com->where);
+ /* Add extension attributes to COMMON block declaration. */
+ if (com->head)
+ {
+ attributes = NULL_TREE;
+ for (id = 0; id < EXT_ATTR_NUM; id++)
+ {
+ if (com->head->attr.ext_attr & (1 << id))
+ {
+ attribute = build_tree_list (
+ get_identifier (ext_attr_list[id].middle_end_name),
+ NULL_TREE);
+ attributes = chainon (attributes, attribute);
+ }
+ }
+ decl_attributes (&decl, attributes, 0);
+ }
+
if (com->threadprivate)
set_decl_tls_model (decl, decl_default_tls_model (decl));
Second, only the line
!GCC$ ATTRIBUTES DLLIMPORT :: a, b
was needed in the main program (right after implicit none), but not any exports anywhere. This is apparently a different syntactical approach then in Intel Fortran, where one imports the COMMON block rather than its constituents. I also found out that I needed to import both a and b even if I only needed b. (When only a was needed, importing a only was enough.)

error using yaml-cpp to get integer nested in key hierarchy

Initial Question
I have a config.yaml that has structure similar to
some_other_key: 34
a:
b:
c:
d: 3
I thought I could do
YAML::Node config = YAML::LoadFile(config_filename.c_str());
int x = config["a"]["b"]["c"]["d"].as<int>();
but I get
terminate called after throwing an instance of
'YAML::TypedBadConversion<int>'
what(): bad conversion
How do I descend through my config.yaml to extract a value like this? I also get that same exception if I mistype one of the keys in the path, so I can't tell from the error if I am accidentally working with a null node or if there is a problem converting a valid node's value to int
Follow up After First Replies
Thank you for replying! Maybe it is an issue with what is in the config.yaml? Here is a small example to reproduce,
yaml file: config2.yaml
daq_writer:
num: 3
num_per_host: 3
hosts:
- local
datasets:
small:
chunksize: 600
Python can read it:
Incidentally, I am on linux on rhel7, but from a python 3.6 environment, everything looks good:
$ python -c "import yaml; print(yaml.load(open('config2.yaml','r')))"
{'daq_writer': {'num_per_host': 3, 'num': 3, 'datasets': {'small': {'chunksize': 600}}, 'hosts': ['local']}}
C++ yaml-cpp code
The file yamlex.cpp:
#include <string>
#include <iostream>
#include "yaml-cpp/yaml.h"
int main() {
YAML::Node config = YAML::LoadFile("config2.yaml");
int small_chunksize = config["daq_writer"]["datasets"]["smal"]["chunksize"].as<int>();
}
When I compile and run this, I get:
(lc2) psanagpu101: ~/rel/lc2-hdf5-110 $ c++ --std=c++11 -Iinclude -Llib -lyaml-cpp yamlex.cpp
(lc2) psanagpu101: ~/rel/lc2-hdf5-110 $ LD_LIBRARY_PATH=lib ./a.out
terminate called after throwing an instance of 'YAML::TypedBadConversion<int>'
what(): bad conversion
Aborted (core dumped)
(lc2) psanagpu101: ~/rel/lc2-hdf5-110 $ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
I have been able to read top level keys, like the some_other_key that I referenced above, but I got an error when I went after this nested key. Good to know that syntax works!
You have a typo in your keys: instead of "small", you wrote "smal".

LLVM ScalarEvolution Pass Cannot Compute Exit Count for Loop Vectorizer

I'm trying to figure out how to run LLVM's built-in loop vectorizer. I have a small program containing an extremely simple loop (I had some output at one point which is why stdio.h is still being included despite never being used):
1 #include <stdio.h>
2
3 unsigned NUM_ELS = 10000;
4
5 int main() {
6 int A[NUM_ELS];
7
8 #pragma clang loop vectorize(enable)
9 for (int i = 0; i < NUM_ELS; ++i) {
10 A[i] = i*2;
11 }
12
13 return 0;
14 }
As you can see, it does nothing at all useful; I just need the for loop to be vectorizable. I'm compiling it to LLVM bytecode with
clang -emit-llvm -O0 -c loop1.c -o loop1.bc
llvm-dis -f loop1.bc
Then I'm applying the vectorizer with
opt -loop-vectorize -force-vector-width=4 -S -debug loop1.ll
However, the debug output gives me this:
LV: Checking a loop in "main" from loop1.bc
LV: Loop hints: force=? width=4 unroll=0
LV: Found a loop: for.cond
LV: SCEV could not compute the loop exit count.
LV: Not vectorizing: Cannot prove legality.
I've dug around in the LLVM source a bit, and it looks like SCEV comes from the ScalarEvolution pass, which has the task of (among other things) counting the number of back edges back to the loop condition, which in this case (if I'm not mistaken) should be the trip count minus the first trip (so 9,999 in this case). I've run this pass on a much larger benchmark and it gives me the exact same error at every loop, so I'm guessing it isn't the loop itself, but that I'm not giving it enough information.
I've spent quite a bit of time combing through the documentation and Google results to find an example of a full opt command using this transformation, but have been unsuccessful so far; I'd appreciate any hints as to what I may be missing (I'm new to vectorizing code so it could be something very obvious).
Thank you,
Stephen
vectorization depends on number of other optimization which needs to be run before. They are not run at all at -O0, therefore you cannot expect that your code would be 'just' vectorized there.
Adding -O2 before -loop-vectorize in opt cmdline would help here (make sure your 'A' array is external / used somehow, otherwise everything will be optimized away).

creat system call fail to set permissions

I need to use creat system call to create file (it is used in legacy code and I'm not allowed to change this; example below is simplified one but the problem is just the same). I have the following code:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
umask(0);
int hndl = creat("abc.dat", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); // == 0660
close(hndl);
}
File is created as expected (I checked the timestamp also), but the permissions are different from 0660:
$ gcc creat.c && ./a.out && ll | grep abc
-rwx---r-x 1 ulysses ulysses 0 May 7 19:42 abc.dat*
which are 0705. I tried to use 0660 literally and had the same result. Am I missing something?
Your code looks correct and should do what you want. You should check whether your program actually did create the file: if it did exist already, creat() would succeed without error and update the timestamp, but not change the permissions.