Header files in PROS

So I have a weird problem with PROS for V5. I am trying to use header files to use a certain function (initComplete()) I wrote in one file (joystick.cpp), and access it in initialize.cpp. joystick.cpp has an accompanying .hpp that also has the function defined, and everything is linked through main.h. Whenever I try to compile it, PROS yells at me for “use of undeclared identifier ‘initComplete’”

Here’s my code:

main.h


/**
 * \file main.h
 *
 * Contains common definitions and header files used throughout your PROS
 * project.
 *
 * Copyright (c) 2017-2018, Purdue University ACM SIGBots.
 * All rights reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef _PROS_MAIN_H_
#define _PROS_MAIN_H_

/**
 * If defined, some commonly used enums will have preprocessor macros which give
 * a shorter, more convenient naming pattern. If this isn't desired, simply
 * comment the following line out.
 *
 * For instance, E_CONTROLLER_MASTER has a shorter name: CONTROLLER_MASTER.
 * E_CONTROLLER_MASTER is pedantically correct within the PROS styleguide, but
 * not convienent for most student programmers.
 */
#define PROS_USE_SIMPLE_NAMES

/**
 * If defined, C++ literals will be available for use. All literals are in the
 * pros::literals namespace.
 *
 * For instance, you can do `4_mtr = 50` to set motor 4's target velocity to 50
 */
#define PROS_USE_LITERALS

#include "api.h"
#include "joystick.hpp"
#include "drive.hpp"

/**
 * You should add more #includes here
 */
//#include "okapi/api.hpp"
//#include "pros/api_legacy.h"

/**
 * If you find doing pros::Motor() to be tedious and you'd prefer just to do
 * Motor, you can use the namespace with the following commented out line.
 *
 * IMPORTANT: Only the okapi or pros namespace may be used, not both
 * concurrently! The okapi namespace will export all symbols inside the pros
 * namespace.
 */
using namespace pros;
// using namespace pros::literals;
// using namespace okapi;

/**
 * Prototypes for the competition control tasks are redefined here to ensure
 * that they can be called from user code (i.e. calling autonomous from a
 * button press in opcontrol() for testing purposes).
 */
#ifdef __cplusplus
extern "C" {
#endif
void autonomous(void);
void initialize(void);
void disabled(void);
void competition_initialize(void);
void opcontrol(void);
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
/**
 * You can add C++-only headers here
 */
//#include <iostream>
#endif

#endif  // _PROS_MAIN_H_

joystick.hpp


#ifdef _JOYSTICK_HPP_
#define _JOYSTICK_HPP_

void initComplete();

bool botIsInitialized();

int getDriveControl();

int getTurnControl();

#endif

joystick.cpp


#include "main.h"
#include "joystick.hpp"

Controller master(CONTROLLER_MASTER);

int driveControl = 0;
int turnControl = 0;
bool botInitialized = false;

void initComplete() {
  botInitialized = true;
}

bool botIsInitialized() {
  return botInitialized;
}

int getDriveControl() {
  return driveControl;
}

int getTurnControl() {
  return turnControl;
}

void joystickFunction(void* param) {
  driveControl = master.get_analog(ANALOG_LEFT_Y);
  turnControl = master.get_analog(ANALOG_LEFT_X);
}

Task joystickTask(joystickFunction, (void*)"PROS", TASK_PRIORITY_DEFAULT, TASK_STACK_DEPTH_DEFAULT, "Joystick");

initialize.cpp


#include "main.h"

/**
 * Runs initialization code. This occurs as soon as the program is started.
 *
 * All other competition modes are blocked by initialize; it is recommended
 * to keep execution time for this mode under a few seconds.
 */
void initialize() {
	lcd::initialize();
	initComplete();
}

/**
 * Runs while the robot is in the disabled state of Field Management System or
 * the VEX Competition Switch, following either autonomous or opcontrol. When
 * the robot is enabled, this task will exit.
 */
void disabled() {}

/**
 * Runs after initialize(), and before autonomous when connected to the Field
 * Management System or the VEX Competition Switch. This is intended for
 * competition-specific initialization routines, such as an autonomous selector
 * on the LCD.
 *
 * This task will exit when the robot is enabled and autonomous or opcontrol
 * starts.
 */
void competition_initialize() {}

So yeah, as far as I can tell there shouldn’t be anything wrong with this, but it still hates me.
RIP me

Here’s your problem:

#ifdef _JOYSTICK_HPP_
#define _JOYSTICK_HPP_

Should be #ifndef instead of #ifdef. It is treating your joystick.hpp as a blank file because of this mistake.

you can use “#pragma once” to replace “#ifdef