C++ static initialization of pointers/references between translation units - variables

First off, I have scoured stack overflow and the rest of the web and I am well aware of the following:
1) Global variables are Bad
2) Global variables dependencies between translation units is bad
However, we are using some middleware that is doing the following; and I can not ascertain whether this is dangerous.
// Global_Variable.hpp
#include "Type.hpp" /* this defines the type as a structure, doesn't really matter :) */
extern Type Global_Variable;
// Global_Variable.cpp
#include "Global_Variable.hpp"
Type Global_Variable = { /* init the struct */ };
// Global_Reference.hpp
#include "Type.hpp"
extern Type & Global_Reference;
// Global_Reference.cpp
#include "Global_Reference.hpp"
#include "Global_Variable.hpp"
Type & Global_Reference = Global_Variable; // does this suffer from the SIOF?
// Global_Pointer.hpp
#include "Type.hpp"
extern Type * Global_Pointer
// Global_Reference.cpp
#include "Global_Pointer.hpp"
#include "Global_Variable.hpp"
Type * Global_Variable = &Global_Variable; // does this suffer from the SIOF?
I am worried that Global_Variable and Global_Reference could be initialized to null rather than Global_Variable, can this be the case?
Thanks!

Related

How can i use a Library for another Library ? [Arduino ESP32] [duplicate]

This question already has answers here:
C++ Global variable declaration
(5 answers)
Closed 9 months ago.
I am working on a project on Arduino ESP32 and I have a lot of Global variables (for data generation). I have decided to create a library in order to orgenise my work a little better. But I use this library into other librari's that I had to create for other usage. after compilation it I have the following error :
sketch\OX2inj_LEVEL_OX2.cpp.o:(.data.addrChipId+0x0): multiple definition of `addrChipId'
sketch\First_Useage.cpp.o:(.data.addrChipId+0x0): first defined here
sketch\OX2inj_LEVEL_OX2.cpp.o:(.bss.ChipID+0x0): multiple definition of `ChipID'
sketch\First_Useage.cpp.o:(.bss.ChipID+0x0): first defined here
here is my .ino (main) code :
#include <Arduino.h>
#include "Var_Str_EEPROM.h"
#include "Def_Global_Var.h"
#include "First_Useage.h"
//---------somthing
void setup()
{
Serial.begin(115200);
//---------somthing
Serial.println(ChipID.ReadStrEEPROM());
//---------somthing
}
void loop()
{
//---------somthing
}
here is my "Def_Global_Var.h" code
#ifndef Def_Global_Var_H
#define Def_Global_Var_H
#include "Var_Str_EEPROM.h"
uint16_t addrChipId = 1;
VarStrEEPROM ChipID(addrChipId);
#endif
here is my "First_Useage.h" code
#ifndef First_Usage_H
#define First_Usage_H
void getchipid();
#endif
here is my "First_Useage.cpp" code :
#include "First_Useage.h"
#include <Arduino.h>
#include "Var_Str_EEPROM.h"
#include "Def_Global_Var.h"
void getchipid()
{
uint32_t chipId = 0;
for(int i=0; i<17; i=i+8)
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
ChipID.WriteStrEEPROM(String(chipId));
}
My understanding is that, when I use the #include "Def_Global_Var.h", the programme thinks that : "I am calling the library" and it sees that it has been called before and it does not like it.
Is it somehow correct ? and if it is(or not) correct what should I do?
EDIT : sorry I have put the wrong part of the prog. it has been corrected now
The actual cause is that the header is included into several source files, so you end up with multiple conflicting definitions of these variables in your .o files.
You shouldn't normally define global variables in header files at all; you should only declare them as extern:
#ifndef Def_Global_Var_H
#define Def_Global_Var_H
...
extern uint16_t addrChipId;
...
#endif
The second step is to define the variable in the corresponding .cpp file, this time without the extern keyword:
// Def_Global_Var.cpp
uint16_t addrChipId = 1;
Since Def_Global_Var.o gets linked only once, there should be no more conflicts.

AWSSDKCPP S3Client.GetObject

Having issues with GetObject. Intellisense in Visual Studio keeps evaluating the method as GetObjectW
...
unresolved external symbol "__declspec(dllimport) public: virtual class Aws::Utils::Outcome<class Aws::S3::Model::GetObjectResult,class Aws::Client::AWSError > __cdecl Aws::S3::S3Client::GetObjectW(class Aws::S3::Model::GetObjectRequest const &)const " (_imp?GetObjectW#S3Client#S3#Aws##UEBA?AV?$Outcome#VGetObjectResult#Model#S3#Aws##V?$AWSError#W4S3Errors#S3#Aws###Client#4##Utils#3#AEBVGetObjectRequest#Model#23##Z)
Here are my includes
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <aws/s3/model/DeleteObjectRequest.h>
#include <aws/s3/model/GetBucketLocationRequest.h>
#include <aws/s3/model/ListObjectsRequest.h>
All other methods work. Put works, Delete Works, Lists work. it all works. the projects are set to VS 2017. I am ONLY having problems with GetObject and as I said intellisense sees every other method except GetObject which it evaluates to GetObjectW
Client::ClientConfiguration config;
config.region = Region::US_EAST_2;
config.scheme = Http::Scheme::HTTPS;
config.connectTimeoutMs = 30000;
config.requestTimeoutMs = 30000;
S3Client s3Client(Auth::AWSCredentials(ACCESS_KEY, SECRET_KEY), config);
GetObjectRequest getObjectRequest;
getObjectRequest.WithBucket(bucket)
.WithKey(fileKey);
// //GetObject is Having issues here where it is not being found in referenced assembly it keeps being called GetObjectW...
// //It is perhaps the case there is a missing required reference for the method?
GetObjectOutcome getObjectOutcome = s3Client.GetObject(getObjectRequest);
resolved on https://github.com/aws/aws-sdk-cpp/issues/625
answer is:
must #undef GetObject before aws includes as follows:
#undef GetObject
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/GetObjectRequest.h>
This is a conflict with Windows.h

TFLite: Micro mutable Op Resolver does not name a type

I am trying to compile a TFLite micro-based Arduino sketch using MicroMutableOpsResolver class (to only include required operations for reducing the memory usage).
Though see similar usage in TF lite example here - https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/micro_speech/micro_speech_test.cc
But keep hitting the below compilation error.
IMU_Classifier_TinyML:22:1: error: 'micro_op_resolver' does not name a type
micro_op_resolver.AddFullyConnected();
^~~~~~~~~~~~~~~~~
IMU_Classifier_TinyML:23:1: error: 'micro_op_resolver' does not name a type
micro_op_resolver.AddSoftmax();
^~~~~~~~~~~~~~~~~
IMU_Classifier_TinyML:24:1: error: 'micro_op_resolver' does not name a type
micro_op_resolver.AddRelu();
^~~~~~~~~~~~~~~~~
Using library Arduino_LSM9DS1 at version 1.1.0 in folder: /home/balaji/Arduino/libraries/Arduino_LSM9DS1
Using library Wire in folder: /home/balaji/.arduino15/packages/arduino/hardware/mbed/1.3.2/libraries/Wire (legacy)
Using library Arduino_TensorFlowLite at version 2.4.0-ALPHA in folder: /home/balaji/Arduino/libraries/Arduino_TensorFlowLite
exit status 1
'micro_op_resolver' does not name a type
The code snippet looks as below:
#include <Arduino_LSM9DS1.h>
#include <TensorFlowLite.h>
#include <tensorflow/lite/micro/micro_mutable_op_resolver.h>
#include <tensorflow/lite/micro/kernels/micro_ops.h>
#include <tensorflow/lite/micro/micro_error_reporter.h>
#include <tensorflow/lite/micro/micro_interpreter.h>
#include <tensorflow/lite/schema/schema_generated.h>
#include <tensorflow/lite/version.h>
// Include the TFlite converted model header file
#include "model.h"
const float accelThreshold = 2.5;
const int numOfSamples = 119; // acceleration sample-rate
int samplesRead = numOfSamples;
tflite::MicroErrorReporter tfLiteErrorReporter;
/*Import only the required ops to reduce the memory usage*/
static tflite::MicroMutableOpResolver<3> micro_op_resolver;
micro_op_resolver.AddFullyConnected();
micro_op_resolver.AddSoftmax();
micro_op_resolver.AddRelu();
Am I missing any dependency or could this be due to TF lite version mismatch?
At least the function calls like micro_op_resolver.AddFullyConnected(); must be placed into a function body. Something like this should compile:
#include <Arduino_LSM9DS1.h>
#include <TensorFlowLite.h>
#include <tensorflow/lite/micro/micro_mutable_op_resolver.h>
#include <tensorflow/lite/micro/kernels/micro_ops.h>
#include <tensorflow/lite/micro/micro_error_reporter.h>
#include <tensorflow/lite/micro/micro_interpreter.h>
#include <tensorflow/lite/schema/schema_generated.h>
#include <tensorflow/lite/version.h>
// Include the TFlite converted model header file
#include "model.h"
const float accelThreshold = 2.5;
const int numOfSamples = 119; // acceleration sample-rate
int samplesRead = numOfSamples;
tflite::MicroErrorReporter tfLiteErrorReporter;
/*Import only the required ops to reduce the memory usage*/
static tflite::MicroMutableOpResolver<3> micro_op_resolver;
void setup() {
micro_op_resolver.AddFullyConnected();
micro_op_resolver.AddSoftmax();
micro_op_resolver.AddRelu();
}
void loop() {
// put your main code here, to run repeatedly:
}

Avoid header processing in my Virtual FS module

I want to write a module that serves a huge virtual .wav file (also plan to add a virtual .ogg file in the future).
I know the size of the file (2Gb) and its fake modification time (2000-01-01 0:00:00) and I have a function to read portion of the file:
void virtwav_read(void *buf, ssize_t bufsz, uint32_t virtofs);
I want to hook the low-level file operations like stat, read, seek, etc. The standard apache code should take care of parsing the headers (including range requests, cache-related stuff) and generate Content-Type, Content-Length, ETag, Last-Modified, etc.
Parsing the request_rec.range is not a big deal. What worries me more is sending the right cache-related headers and HTTP 206 and 304 when approprate. I'm sure apache would do that better than my code.
I thought that setting request_rec.mtime and request_rec.clength would do the trick, but they don't seem to be output fields.
Lastly, VFS is surprisingly unpopular topic. I found only one ancient project http://apvfs.sourceforge.net/ dated 2003.
Here's my minimal module and its config. The right Content-Type is added by apache, but no ETag
LoadModule virtwav_module modules/mod_virtwav.so
AddHandler virtwav-handler .wav
_
#include "apr_hash.h"
#include "ap_config.h"
#include "ap_provider.h"
#include "httpd.h"
#include "http_core.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include <unistd.h> /* for sleep() */
static int example_handler(request_rec *r)
{
if (!r->handler || strcmp(r->handler, "virtwav-handler")) return (DECLINED);
//r->clength = 42;
//r->mtime = apr_time_now();
ap_rprintf(r, "clength: %" APR_INT64_T_FMT "\n", (apr_int64_t)r->clength);
ap_rprintf(r, "mtime: %" APR_INT64_T_FMT "\n", (apr_int64_t)r->mtime);
ap_rwrite("dummy", 5, r);
ap_rflush(r);
sleep(50);
return OK;
}
static void register_hooks(apr_pool_t *pool)
{
/* Create a hook in the request handler, so we get called when a request arrives */
ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
// ap_hook_dirwalk_stat ?
// This hook allows modules to handle/emulate the apr_stat()
// ap_hook_map_to_storage ?
// This hook allow modules to set the per_dir_config based on their own
}
module AP_MODULE_DECLARE_DATA virtwav_module =
{
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
register_hooks /* Our hook registering function */
};

Separating Code To Be Organized

I'm building a zipper application, but it has a declaration that I want to separate it in another file (compress-file.m), but only when I separate the files I got an error when compiling with a variable, see it:
[ubuntu#eeepc:~/Desktop] make
This is gnustep-make 2.0.2. Type 'make print-gnustep-make-help' for help.
Making all for app LeafZip...
Creating LeafZip.app/....
Compiling file main.m ...
main.m: In function ‘main’:
main.m:7: error: ‘PATH_MAX’ undeclared (first use in this function)
main.m:7: error: (Each undeclared identifier is reported only once
main.m:7: error: for each function it appears in.)
main.m:12: warning: implicit declaration of function ‘compressFile’
main.m:7: warning: unused variable ‘outFileName’
make[1]: *** [obj/main.o] Error 1
make: *** [LeafZip.all.app.variables] Error 2
Also see the line 7 of main.m file:
char outFileName[PATH_MAX] = { 0 };
And see some lines of compress-file.m:
#include <stdio.h>
#include <zlib.h>
#include <limits.h>
/* Buffer to hold data read */
char buf[BUFSIZ] = { 0 };
size_t bytes_read = 0;
gzFile *out = gzopen(outFileName, "wb");
I know that is Objective-C extension, but it's only because when I solve this problem I will need to continue the development in Objective-C. What I need to do to correct this?
PATH_MAX is not always defined by including <limits.h>. If you want to use it, you probably need to fall back on the fragment:
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX _POSIX_PATH_MAX /* Or possibly _XOPEN_PATH_MAX */
#endif /* PATH_MAX */
Did you even include limits.h in your main program? If not, you need to do so.
Looks like main.m needs to #include <limits.h>. It also seems like it will need to include a header describing compressFile (which I guess you moved into compress-file.m.