Compilation error but no error in console

Hello,

I have been working on a program to record and save driver runs to be run in autonomous. It’s mostly done, but when compiling, a “compilation failed” error message occurs, even though Coding Studio doesn’t highlight any issues in the code.

If you want, I could post some of the code used in the program to help with debugging. Some things to note are that I am using C++ libraries


<cstdlib>

for string to int conversion, and


<fstream>

to save, read, and edit auton runs. It’s possible that fstream is somehow unsupported on the V5 brain, which is why it isn’t compiling, as it’s separate from the V5 brain’s SD card functions. If that’s the case, then are there any examples showing how to read a file with the brain’s SD card functions?

Console output:

8:00:12 -- info -- changed directory: C:/Users/andy/AppData/Local/VEX Coding Studio/VEX Coding Studio/sdk/user/
18:00:12 -- info -- C:/Users/andy/AppData/Local/VEX Coding Studio/VEX Coding Studio/sdk/user/
18:00:12 -- info -- clang version 5.0.1 (tags/RELEASE_501/final) 
Target: thumbv7-none--eabi 
Thread model: posix 
InstalledDir: C:\Program Files (x86)\VEX Robotics\VEX Coding Studio\node_modules\@modkit\modkit-compiler-binaries-windows\clang\bin 
 "C:\\Program Files (x86)\\VEX Robotics\\VEX Coding Studio\\node_modules\\@modkit\\modkit-compiler-binaries-windows\\clang\\bin\\clang.exe" -cc1 -triple armv7-none--eabi -emit-obj -disable-free -disable-llvm-verifier -discard-value-names -main-file-name cxx_entry.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -no-integrated-as -mconstructor-aliases -nostdsysteminc -target-cpu generic -target-feature +soft-float-abi -target-feature -fp-only-sp -target-feature -d16 -target-feature +vfp3 -target-feature -fp16 -target-feature -vfp4 -target-feature -fp-armv8 -target-feature +neon -target-feature -crypto -target-feature +strict-align -target-abi aapcs -mfloat-abi soft -v -dwarf-column-info -debugger-tuning=gdb -ffunction-sections -fdata-sections -coverage-notes-file "C:\\Users\\andy\\AppData\\Local\\VEX Coding Studio\\VEX Coding Studio\\sdk\\user\\cxx.gcno" -nostdinc++ -resource-dir "C:\\Program Files (x86)\\VEX Robotics\\VEX Coding Studio\\node_modules\\@modkit\\modkit-compiler-binaries-windows\\clang\\lib\\clang\\5.0.1" -D _LIBCPP_HAS_NO_EXCEPTIONS -D _LIBCPP_HAS_NO_THREADS -D VexV5 -I . -I ../clang/7.0.0/include -I ../vexv5/include -I ../vexv5/gcc/include -I ../vexv5/gcc/include/c++/4.9.3 -I ../vexv5/gcc/include/c++/4.9.3/arm-none-eabi/armv7-ar/thumb -I ../modkit -internal-isystem "C:\\Program Files (x86)\\VEX Robotics\\VEX Coding Studio\\node_modules\\@modkit\\modkit-compiler-binaries-windows\\clang\\lib\\clang\\5.0.1\\include" -internal-isystem include -Os -Wno-unknown-attributes -Werror=return-type -Wall -std=gnu++11 -fdeprecated-macro -fdebug-compilation-dir "C:\\Users\\andy\\AppData\\Local\\VEX Coding Studio\\VEX Coding Studio\\sdk\\user" -ferror-limit 19 -fmessage-length 0 -fallow-half-arguments-and-returns -fno-rtti -fshort-enums -fno-signed-char -fno-threadsafe-statics -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o cxx.o -x c++ cxx_entry.cpp 
clang -cc1 version 5.0.1 based upon LLVM 5.0.1 default target i686-pc-windows-msvc 
ignoring nonexistent directory "C:\Program Files (x86)\VEX Robotics\VEX Coding Studio\node_modules\@modkit\modkit-compiler-binaries-windows\clang\lib\clang\5.0.1\include" 
ignoring nonexistent directory "include" 
ignoring nonexistent directory "C:\Program Files (x86)\VEX Robotics\VEX Coding Studio\node_modules\@modkit\modkit-compiler-binaries-windows\clang\lib\clang\5.0.1\include" 
#include "..." search starts here: 
#include <...> search starts here: 
 . 
 ../clang/7.0.0/include 
 ../vexv5/include 
 ../vexv5/gcc/include 
 ../vexv5/gcc/include/c++/4.9.3 
 ../vexv5/gcc/include/c++/4.9.3/arm-none-eabi/armv7-ar/thumb 
 ../modkit 
End of search list. 
18:00:12 -- info -- make process failed with return code: 1

probably easiest to just send me the code and I will have a look.
it is possible to use fstream, but we found some issues when used in certain ways in VCS 1.0, the problem is with the build system so it is technically possible to patch, but there are also other workarounds. This type of code will work (from some test code)

    // create a file with long filename
    std::ofstream ofs ("a_long_filename_debug.txt", std::ofstream::out);
    ofs << "lorem ipsum\r\n";
    ofs << "this was a test of a file with long file name\r\n";
    ofs.close();

    // try reading it        
    std::ifstream ifs;
    ifs.open("a_long_filename_debug.txt", std::ios::binary);
      
    if (ifs.is_open()) {
      ifs.seekg (0, ifs.end);
      int len = ifs.tellg();
      ifs.seekg (0, ifs.beg);
    
      char * buffer = new char [len+1];
      
      std::cout << "length is " << len << "\r" << std::endl;
      ifs.read(buffer, len);
      buffer[len] = 0;
      std::cout << buffer;
      ifs.close();           

      delete] buffer;
    }
    else
      std::cout << "open file error, errno: " << errno << "\r\n";

but it’s usually best to make the stream instances global rather than local to a function, depending on how and when they are instantiated it can cause link errors which is what you are probably experiencing.

@jpearman here is what I have, using


fstream

. I can try using


ofstream

and


ifstream

if that will make any difference.

#include "robot-config.h"
#include <fstream>
#include <sstream>



vex::competition    Competition;

using namespace vex;
using namespace std;

//@author Andy Herbert
//team 254


class autoRecorder{
    private:
    static fstream file;
    static string fileName;
    static int time;
    static int fileNum;
    
    static string autonSaveName;
    static vex::brain *Brain;
    static vex::controller *Controller[2];
    static bool hasPressedScreen;
    
    public:
    static int axisValues[2][4];//when playing back auton, represents controller axis
    static bool buttonValues[2][12]; //when playing back auton, represents controller buttons
    static int prevAxisValues[2][4];
    static bool prevButtonValues[2][12];
    
    private:
    static void screenPressed(){hasPressedScreen = true;};
    static void screenReleased(){hasPressedScreen = false;};
    
    static void collectControllerValues(){
        for(int i = 0; i < sizeof(axisValues)/sizeof(*axisValues); i++)
            for(int ii = 0; ii < sizeof(axisValues*)/sizeof(*axisValues*); ii++)
                prevAxisValues*[ii] = axisValues*[ii];
        for(int i = 0; i < sizeof(buttonValues)/sizeof(*buttonValues); i++)
            for(int ii = 0; ii < sizeof(buttonValues*)/sizeof(*buttonValues*); ii++)
                prevButtonValues*[ii] = buttonValues*[ii];
        for(int i = 0; i < sizeof(Controller)/sizeof(*Controller); i++){
            /*saving a bunch of stuff to arrays*/
        }
    }
    
    static bool controllerChange(int index, bool axis = true){
        /*code not shown; no use of fstream*/
    }
    
    static bool controllerChange(){
        /*code not shown; no use of fstream*/
    }
    
    static void writeChangedValuesToFile(){
        collectControllerValues();
        for(int ii = 0; ii < sizeof(axisValues)/sizeof(*axisValues); ii++){
            for (int i = 0; i < sizeof(axisValues[ii])/sizeof(*axisValues[ii]); i++){
                if (axisValues[ii]* != prevAxisValues[ii]*) file << time << ";"  << ii << ";" << i << ";axis;" << axisValues[ii]* <<  ";\n";
            }
        }
        for(int ii = 0; ii < sizeof(buttonValues)/sizeof(*buttonValues); ii++){
            for (int i = 0; i < sizeof(buttonValues[ii])/sizeof(*buttonValues[ii]); i++){
                if (buttonValues[ii]* != prevButtonValues[ii]*) file << time << ";"  << ii << ";" << i << ";button;" << buttonValues[ii]* <<  ";\n";
            }
        }
    }
    public:
    autoRecorder(brain *Brain, controller *Controller[2], string fileName = "autoAuton"){
        this->Brain = Brain;
        for(int i = 0; i < sizeof(this->Controller)/sizeof(*(this->Controller)); i++)
            this->Controller* = Controller*;
        Brain->Screen.pressed(screenPressed);
        Brain->Screen.released(screenReleased);
        fileNum = -1;
        autonSaveName = fileName;
        hasPressedScreen = false;
    };
    
    autoRecorder(brain *Brain, controller *Controller, string fileName = "autoAuton") {
        this->Controller[0] = Controller;
        autoRecorder(Brain, this->Controller, fileName);
    };

void recordAuton(){
        file.close();
        fileNum++;
        char numstr[21]; // enough to hold all numbers up to 64-bits
        sprintf(numstr, "%d", fileNum);
        file.open(autonSaveName + numstr);
        Controller[0]->Screen.print("Ready to record.");
        Controller[0]->Screen.newLine();
        Controller[0]->Screen.print("Touch the cortex screen to begin.");
        while(!hasPressedScreen){}
        while(hasPressedScreen){}
        int time = 0;
        //put initializing code here
        while(!hasPressedScreen){
            Brain->Screen.drawRectangle(1,1,50,20);
            time++;
            task::sleep(1);
        }
        while(hasPressedScreen){}
        
    };

    private: static void tAuton(){
        file.open(fileName);
                string currLine;
                while(getline(file, currLine)){
                    //time;index1;index2;controller/axis;value;\n
                    //this can be simplified but ill do it later if its a big deal
                    int index = currLine.find(";");
                    stringstream lineStr(currLine.substr(0, index));
                    int timeRec;
                    lineStr >> timeRec;
                    int oldIndex = index;
                    index = currLine.find(";", oldIndex+1);
                    lineStr.str(currLine.substr(oldIndex+1, index));
                    int ind1Rec;
                    lineStr >> ind1Rec;
                    oldIndex = index;
                    index = currLine.find(";", oldIndex+1);
                    lineStr.str(currLine.substr(oldIndex+1, index));
                    int ind2Rec;
                    lineStr >> ind2Rec;
                    oldIndex = index;
                    index = currLine.find(";", oldIndex+1);
                    string type = currLine.substr(oldIndex+1, index);
                    oldIndex = index;
                    index = currLine.find(";", oldIndex+1);
                    lineStr.str(currLine.substr(oldIndex+1, index));
                    int valRec;
                    lineStr >> valRec;
                    while(time < timeRec){
                        time++;
                        task::sleep(1);
                    }
                    if(type.compare("axis")) axisValues[ind1Rec][ind2Rec] = valRec;
                    else buttonValues[ind1Rec][ind2Rec] = valRec;
                }
    }
    
    public: static void playAuton(string autonLoad){
        fileName = autonLoad;
        thread th(tAuton);
        th.detach();
    }
};

@jpearman I just tested your code in a new file, and the same error with no error happened again. No line error, but it won’t compile either.

you probably have link errors, VCS does not show those. It’s hard to tell just from the above code as if I try and use that it just throws errors on all the static class variables you haven’t defined anywhere,

I found the problem wasn’t necessarily with fstream, but rather with the class itself… I removed the class entirely and my current code compiles fine. Why might there be an issue with how I set up the class?

Well how could I fix the class itself because I am having the same issue