I read different answers about VLA on SO but couldn't find the answer. In my case, I have one function that allocates memory:
template<typename T>
void allocMemory(T *&data, const size_t numElems)
{
#ifdef PINNED_MEMORY
// allocate pinned memory
#else
data = new T[numElems];
#endif
}
Now, I have a vector class where I use this method:
template<typename T>
class MyVec
{
T *data;
size_t size;
public:
MyVec(size_t _size): size(_size)
{ allocMemory<T>(data, size); } // gives VLA warning
};
It happens when I compile it using nvcc (V0.2.1221) compiler which I guess uses gcc compiler underneath (?) The actual warning is:
myvec.h:16:6: warning: ISO C++ does not support variable-length array types [-Wvla]
data = new T[numElems];
I think you don't compile your project the right way.
Try to using the flowing make file.
CUDA_INSTALL_PATH := /usr/local/cuda
CXX := g++
CC := gcc
LINK := g++ -fPIC
NVCC := nvcc
#Includes
INCLUDES = -I. -I$(CUDA_INSTALL_PATH)/include
#Common flags
COMMONFLAGS += $(INCLUDES)
NVCCFLAGS += $(COMMONFLAGS)
CXXFLAGS += $(COMMONFLAGS)
CFLAGS += $(COMMONFLAGS)
LIB_CUDA := -L$(CUDA_INSTALL_PATH)/lib -lcudart
#OBJS = GpuSolver.cu.o main.cpp.o
OBJS = main.cu.o a.cpp.o # your files
TARGET = a.out
LINKLINE = $(LINK) -o $(TARGET) $(OBJS) $(LIB_CUDA)
.SUFFIXES: .c .cpp .cu .o
%.c.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
.cu.o: %.cu
$(NVCC) $(NVCCFLAGS) -c $< -o $#
%.cpp.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
$(TARGET): $(OBJS) "makefile" #your makefile file name
$(LINKLINE)
Related
To make this short, I have a CPP and C code, and my CPP code is trying to reference functions from the C code with a header file. Whenever I run the make command, I end up getting "undefined reference" errors. Here are my codes:
cpp_code.cpp:
extern "C"{
#include "header_code.h";
}
int main(){
cout << "Hello" << endl;
return 0;
}
c_code.c:
#include "header_code.h"
int main(){
printf("Hello");
return 0;
}
void initalize(){
printf("Initilized");
}
header_code.h:
extern void initalize();
makefile:
CXX = g++
CXXFLAGS = -std=c++11
CC = gcc
DEPS = header_code.h
CFLAGS = -I
OBJS = cpp_code.o c_code.o
c: $(OBJS)
$(CXX) -o $# $^ $(CXXFLAGS)
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $<
%.o : %.c $(DEPS)
$(CC) -c $(CFLAGS) $<
Whenever running make it always gives me problems. Can anyone please help me? Thank you for your time reading all of this!
[basic.start.main]
A program that declares a variable main at global scope, or that declares a function main at global scope attached to a named module, or that declares the name main with C language linkage (in any namespace) is ill-formed.
So, as a C++ program, it's ill-formed. Remove the C main function.
Other problems:
In the makefile you have
CFLAGS = -I
and whatever comes after that when compiling will be treated as a directory to search for header files in. In your makefile, that's the source file. Correction:
CFLAGS =
or
CFLAGS = -I.
Your header file is missing a header guard and header files that are supposed to be used by both C and C++ code usually contain the extern "C" part themselves to not burden C++ users to add it.
cpp_code.cpp
#include "header_code.h"
#include <iostream>
int main() {
initalize(); // call the C function
std::cout << "Hello" << std::endl;
}
c_code.c
#include "header_code.h"
#include <stdio.h>
void initalize(){
printf("Initilized");
}
header_code.h
#ifndef HEADER_CODE_H_
#define HEADER_CODE_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void initalize();
#ifdef __cplusplus
}
#endif
#endif
makefile
CXX = g++
CXXFLAGS = -std=c++11
CC = gcc
DEPS = header_code.h
CFLAGS = -I.
OBJS = cpp_code.o c_code.o
c: $(OBJS)
$(CXX) -o $# $^ $(CXXFLAGS)
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $<
%.o : %.c $(DEPS)
$(CC) -c $(CFLAGS) $<
I've looked at several posts of the same questions on here and as far as I've figured I've done what they said to do. However, I still get a "undefined reference to `cmb::functionA()'" warning.
I have the header:
//combine.h
#ifndef COMBINE_H
#define COMBINE_H
namespace cmb
{
void functionA();
}
#endif
Function source file:
// combine.cc
#include <iostream>
#include "combine.h"
using namespace std;
namespace cmb
{
void functionA()
{
cout << "print something\n";
}
}
And main:
//main.cc
#include "combine.h"
using namespace std;
using namespace cmd;
int main(int argc, char *argv[])
{
functionA();
}
It is now working when compiling manually (g++ -o Test *.cc -Wall --std=c++17) but using make still gives me the same error. I really don't understand make files so any help would be appreciated.
makefile:
CXX := g++
CXXFLAGS += -Wall -std=c++17
LIBSRCS = $(filter-out main.cc,$(shell find -name \*.cc))
LIBOBJS = $(patsubst %.cc,%.o,$(LIBSRCS))
main: main.o combine.o libproject.a
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $# $<
$(LIBOBJS): %.o: %.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<
libproject.a: $(LIBOBJS)
ar rcs $# $^
clean:
rm -f libproject.a $(LIBOBJS)
.PHONY: clean
I just use make main in terminal.
You must add combine.o after main: in the makefile.
Since you use a library, you need to tell the linker to use it (LDFLAGS), and it should be after the main in g++ command. As in previous comments, the using namespace cmd needed to be changed to cmb
This one worked for me:
CXX := g++
CXXFLAGS += -Wall -std=c++17
LIBSRCS = $(filter-out ./main.cc,$(shell find -name \*.cc))
LIBOBJS = $(patsubst %.cc,%.o,$(LIBSRCS))
LDFLAGS += -L. -lproject
main: main.o libproject.a
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# $< $(LDFLAGS)
libproject.a: $(LIBOBJS)
ar rcs $# $^
.PHONY: clean
clean:
rm -f libproject.a $(LIBOBJS) main main.o
I also needed to add ./ in filtering out main.cc
Example run:
jontte#jontte-Latitude-E5420:~/Temp/maketest$ make
g++ -Wall -std=c++17 -c -o main.o main.cc
g++ -Wall -std=c++17 -c -o combine.o combine.cc
ar rcs libproject.a combine.o
g++ -Wall -std=c++17 -o main main.o -L. -lproject
jontte#jontte-Latitude-E5420:~/Temp/maketest$ ./main
print something
jontte#jontte-Latitude-E5420:~/Temp/maketest$ make clean
rm -f libproject.a ./combine.o main main.o
jontte#jontte-Latitude-E5420:~/Temp/maketest$
I am sure this is stupid but i get this linker error
undefined reference to insert_record ,which is a function declared in Operations.hpp,implemented in Operations.cpp and used in main, and i can't find what is wrong in this makefile.
Maybe a pair of rested eyes can spot the problem.
It seems that operations isn't linked although the object is being created.
OBJS = main.o Operations.o CDR.o TBucketList.o RBucketList.o DateTime.o HashTable.o
CC = g++
CXXFLAGS = -W -Wall -Wno-unused -pedantic -c -g
LDFLAGS = -W -Wall -Wno-unused -pedantic -g
werhaus: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o werhaus
main.o : CDR.hpp Operations.hpp HashTable.hpp
$(CC) $(CXXFLAGS) main.cpp
Operations.o : Operations.hpp HashTable.hpp
$(CC) $(CXXFLAGS) Operations.cpp
TBucketList.o : TBucketList.hpp RBucketList.hpp
$(CC) $(CXXFLAGS) TBucketList.cpp
RBucketList.o : RBucketList.hpp
$(CC) $(CXXFLAGS) RBucketList.cpp
HashTable.o : HashTable.hpp TBucketList.hpp
$(CC) $(CXXFLAGS) HashTable.cpp
CDR.o : CDR.hpp DateTime.hpp
$(CC) $(CXXFLAGS) CDR.cpp
DateTime.o : DateTime.hpp
$(CC) $(CXXFLAGS) DateTime.cpp
clean:
\rm *.o werhaus
Update:
main.cpp :
insert_record(originator_number, aCDR, destination_number, hashtable1, hashtable2, BucketSize);
Operations.hpp:
void insert_record(const char*, CDR*, const char*, const Hashtable*, const Hashtable*, int);
Operations.cpp:
void insert_record(const char* originator_number, CDR* aCDR, const char* destination_number, Hashtable* hashtable1, Hashtable* hashtable2, int Bsize)
All seem fine in main..
There does not seem to be an error in your Makefile. As #G.M. noted, the dependencies of .o to corresponding .cpp are missing, these need to be added.
It can be that insert_record declaration in Operations.hpp does not match the definition in Operations.cpp and you end up with two functions insert_record. Check that the function declaration and definitions match: same return type and argument types, both in the same namespace.
I think you should better use something like this:
NAME= werhaus
CXX= g++ # Use CXX for C++
CXXFLAGS= -W -Wall -Wno-unused -pedantic -g
LDFLAGS= -g # No need for warning flags at linking
SRC= main.cpp \
Operations.cpp \
CDR.cpp \
TBucketList.cpp \
RBucketList.cpp \
DateTime.cpp \
HashTable.cpp
OBJS= $(SRC:.cpp=.o)
$(NAME): $(OBJS)
$(CXX) $(LDFLAGS) $(OBJS) -o $(NAME)
all: $(NAME)
%.o: %.cpp
$(CXX) -o $# -c $< $(CXXFLAGS)
clean:
rm -f $(OBJ)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re
This type of makefile will avoid you a lot of errors.
Also, you don't need to put hpp files as dependencies.
Good luck.
In Operations.hpp you have a declaration with signature:
void insert_record(
const char*, CDR*,
const char*,
const Hashtable*,
const Hashtable*,
int)
In Operations.cpp you define a function with the different signature:
void insert_record(
const char* CDR*,
const char*,
Hashtable*,
Hashtable*,
int)
So the declaration in Operations.hpp is not in fact implemented in Operations.cpp
and is undefined.
I have a makefile where I compile a number of cpp files to make different executables.
CFLAGS=-std=c++11 -O3 -Wall -pedantic
CC=g++1
LDFLAGS=
all: auto_variables explict_kw for_each functor member_initializer member_initializer2 reference ref_ptr smart_pointers vector
auto_variables : auto_variables.o
$(CC) $(CFLAGS) auto_variables.o $(LDFLAGS) -o $#
explict_kw : explict_kw.o
$(CC) $(CFLAGS) explict_kw.o $(LDFLAGS) -o $#
for_each : for_each o
$(CC) $(CFLAGS) for_each.o $(LDFLAGS) -o $#
functor : functor.o
$(CC) $(CFLAGS) functor.o $(LDFLAGS) -o $#
member_initializer : member_initializer.o
$(CC) $(CFLAGS) member_initializer.o $(LDFLAGS) -o $#
member_initializer2 : member_initializer2.o
$(CC) $(CFLAGS) member_initializer2.o $(LDFLAGS) -o $#
reference : reference.o
$(CC) $(CFLAGS) reference.o $(LDFLAGS) -o $#
ref_ptr : ref_ptr.o
$(CC) $(CFLAGS) ref_ptr.o $(LDFLAGS) -o $#
smart_pointers : smart_pointers.o
$(CC) $(CFLAGS) smart_pointers.o $(LDFLAGS) -o $#
vector : vector.o
$(CC) $(CFLAGS) vector.o $(LDFLAGS) -o $#
clean:
rm -rf auto_variables explict_kw for_each functor member_initializer member_initializer2 reference ref_ptr smart_pointers vector
rm -rf *.o
I have specified -std=c++11 as CFLAGS but when I type make it doesn't seem to take that option.
g++ -c -o auto_variables.o auto_variables.cpp
auto_variables.cpp:8:27: error: ISO C++ forbids declaration of ‘sum’ with no type [-fpermissive]
auto sum(int x, int y) -> int
^
auto_variables.cpp:8:27: error: top-level declaration of ‘sum’ specifies ‘auto’
auto_variables.cpp:8:27: error: trailing return type only available with -std=c++11 or -std=gnu++11
auto_variables.cpp: In function ‘int main()’:
auto_variables.cpp:16:8: error: ‘var_1’ does not name a type
auto var_1 = 5;
^
auto_variables.cpp:18:8: error: ‘var_2’ does not name a type
auto var_2 = 'c';
^
auto_variables.cpp:20:16: error: ‘var_1’ was not declared in this scope
std::cout << var_1 << std::endl;
^
auto_variables.cpp:21:16: error: ‘var_2’ was not declared in this scope
std::cout << var_2 << std::endl;
^
auto_variables.cpp:23:8: error: ‘fun_sum’ does not name a type
auto fun_sum = [](int a, int b)
^
auto_variables.cpp:46:8: error: ‘itr’ does not name a type
auto itr = mapofStrs.begin();
^
auto_variables.cpp:47:9: error: ‘itr’ was not declared in this scope
while(itr != mapofStrs.end())
^
<builtin>: recipe for target 'auto_variables.o' failed
make: *** [auto_variables.o] Error 1
Why is this happening.
I suggest using CXXFLAGS instead of CFLAGS.
CFLAGS is for C flags while CXXFLAGS is for C++ flags.
CXXFLAGS=-std=c++11 -O3 -Wall -pedantic
Also, it's not clear to me what you meant by:
CC=g++1
Is that a typo? I suspect you meant to use
CC=g++
Keeping with the previous change, you should change that to:
CXX=g++
Then, change all the places where you are using $(CC) $(CFLAS) to $(CXX) $(CXXFLAGS).
This is happening because you are misusing Make.
For C++, use the correct variables, as documented on the GNU Make page: CXXFLAGS.
CXXFLAGS=-std=c++11 -O3 -Wall -pedantic
You shouldn't need to set anything else at least at first.
This will make sure that you are using the correct implicit rules. If this doesn't help, make a Minimal, complete, and verifiable example which shows the code, too.
I am trying to use shared_ptr in c++. I am using MinGw gcc compiler.
My g++ version is 4.8.1.
When I try to use std::shared_ptr, it says it does not name a type.
Is this because it is part of c++ 11, and that is not supported in the compiled I am using?
Or do I need to set a flag to use c++ 11 features?
EDIT: I tried adding the flag to enable c++ to my makefile, and it still gives an error.
My header where shared_ptr is used is as follows
#pragma once
#include <vector>
#include <memory>
namespace WavFileTools
{
class WavFile;
}
class WavFileTools::WavFile
{
public:
typedef std::vector<unsigned char> PCMData8_t;
typedef std::vector<unsigned short int> PCMData16_t;
struct WavFileHeader {
int num_channels;
int sample_rate;
int bits_per_sample;
};
static std::shared_ptr<WavFile> LoadWavFromFile(std::string filename);
private:
WavFile(void);
private:
WavFileHeader m_header;
PCMData16_t m_data16;
PCMData8_t m_data8;
};
And the makefile...
CC := g++
CFLAGS := -g -O2 -std=c++0x
BIN_DIR := bin
BUILD_DIR := build
SRC_DIR := src
MAIN := WavFileTool
TARGET := wavfiletool.exe
SOURCES := $(wildcard src/*.cpp)
OBJECTS := $(SOURCES:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
$(BIN_DIR)/$(TARGET): CREATE_DIRS $(BUILD_DIR)/$(MAIN).o $(OBJECTS)
$(CC) $(OBJECTS) $(CFLAGS) -o $#
$(BUILD_DIR)/$(MAIN).o: $(SRC_DIR)/WavFileTool.cpp
$(CC) $(CFLAGS) -c -o $# $<
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
$(CC) $(CC_FLAGS) -c -o $# $<
CREATE_DIRS:
if not exist $(BIN_DIR) mkdir $(BIN_DIR)
if not exist $(BUILD_DIR) mkdir $(BUILD_DIR)
CLEAN:
if exist $(BIN_DIR) rmdir /Q /S $(BIN_DIR) # /S allows deleting non-empty folder, and /Q prevents confirmation required
if exist $(BUILD_DIR) rmdir /Q /S $(BUILD_DIR)
and the error
In file included from src/WavFile.cpp:1:0:
src/WavFile.h:26:10: error: 'shared_ptr' in namespace 'std' does not name a type
static std::shared_ptr<WavFile> LoadWavFromFile(std::string filename);