Just a guess, but: remove the strings and replace them by enums and/or char*. You mostly use those strings like enums anyways and a simple if on the input chars can get you the enums.
Compiling a C++ to smallest possible size
-
29-06-2022 - |
Frage
I am curious about how I should go about compiling a relatively simple C++ script to its smallest possible executable size.
Without going too much into why this program will be useful, here is my code:
#include <cstdlib>
#include <stdio.h>
#include <string>
using namespace std;
unsigned long long inputAdjust(const string myinput) {
unsigned long long myadjust;
if (myinput=="B") {
myadjust=1;
} else if (myinput=="K") {
myadjust=1024;
} else if (myinput=="M") {
myadjust=1048576;
} else if (myinput=="G") {
myadjust=1073741824;
} else {
myadjust=1;
}
return myadjust;
}
long long asmAnswer (const string myinput, const unsigned long long fir, const unsigned long long sec) {
unsigned long long myanswer;
if (myinput=="A") {
myanswer = fir + sec;
} else if (myinput=="S") {
myanswer = fir - sec;
} else if (myinput=="M") {
myanswer = fir * sec;
} else {
myanswer = fir + sec;
}
return myanswer;
}
double dAnswer (const unsigned long long fir, const unsigned long long sec) {
double myanswer;
myanswer = (double)fir/sec;
return myanswer;
}
void outputAnswer (const string myinput, const long long myanswer) {
if (myinput=="B") {
printf("%lld",myanswer);
} else if (myinput=="K") {
printf("%.2f",(double)(myanswer/1024));
} else if (myinput=="M") {
printf("%.2f",(double)(myanswer/1048576));
} else if (myinput=="G") {
printf("%.2f",(double)(myanswer/1073741824));
} else if (myinput=="O") {
if (myanswer>0) {
if (myanswer<1024 && myanswer>-1024) {
printf("%lld b",myanswer);
} else if (myanswer<1048576 && myanswer>-1048576) {
printf("%.2f kb",(double)(myanswer/1024));
} else if (myanswer<1073741824 && myanswer>-1073741824) {
printf("%.2f mb",(double)(myanswer/1048576));
} else {
printf("%.2f gb",(double)(myanswer/1073741824));
}
}
} else { //assume bytes
printf("%lld",myanswer);
}
}
void outputAnswer (const string myinput, const double myanswer) {
if (myinput=="P") {
printf("%.3f",(myanswer*100.0));
} else {
printf("%.3f",myanswer);
}
}
int main(int argc, char* argv[]) {
if (argc < 5) {
// If we have less than 5 arguments, output the usage
string filename = argv[0];
printf("\nUsage: bytemath.exe BKMG BKMGO[P] ASMD FirstNum SecondNum\n First <OPERATOR> Second\n");
return 0;
} else {
string input = argv[1];
string output = argv[2];
string oper = argv[3];
unsigned long long first = atoll(argv[4]);
unsigned long long second = atoll(argv[5]);
unsigned long i_adjust;
unsigned long o_adjust;
i_adjust = inputAdjust(input);
first *= i_adjust;
second*= i_adjust;
if (oper=="D") { // we want to divide so need to use a double rather than long
double answer;
answer = dAnswer(first, second);
outputAnswer(output, answer);
} else { // otherwise do +, -, or *
long long answer;
answer = asmAnswer(oper, first, second);
outputAnswer(output, answer);
}
return 1;
}
}
Basically it does math operations on large numbers because batch files can only work with 32-bit unsigned integers. I could probably just use something like VBS but this is the solution I'm working with at the moment.
I need the program to be standalone, so it has to statically link to libraries. I was able to get the size down from ~570kb to ~148kb by replacing all the cout
commands with printf
, but I'm wondering what else I can do to get the file size down.
I am compiling this with MiniGW 4.6, and this is my compile command at the moment:
g++ -Os -s -static bytemath.cpp -o bytemath.exe
Anything else I can do to reduce the file size without too much code rewriting?
Thanks.
EDIT
The two big savers were getting rid of <iostream>
and <string>
, which I was able to do by replacing all my cout
commands with printf
and replacing my string comparisons with a char* comparison. For the chars, I needed to make sure to access the 0th element of the array and compare it to a char in single quotes rather than double quotes (i.e. if (myinput[0]=='P') {
rather than if (myinput=="P") {
).
Thanks again everyone! 570kb to 18kb, works for me!
Lösung
Andere Tipps
If you have finished debugging, you can add '-s' to your compiler command. '-s' means strip all symbols. To strip or modifies the symbol table attached to the output of the assembler and link editor can save space after a program has been debugged, and it will also limit dynamically bound symbols
In addition, try to pass std::string by ref instead of by value
change
inputAdjust(const string myinput)
to
inputAdjust(const string& myinput)
This may not help reduce binary size, but it will avoid heap allocation at runtime.