2013-09-18 1 views
0

Мне интересно, как мне следует собирать относительно простой скрипт C++ до наименьшего возможного исполняемого размера.Компиляция C++ до наименьшего возможного размера

Не вдаваясь слишком много в почему эта программа будет полезна, вот мой код:

#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; 
    } 
} 

В основном это делает математические операции на большом количестве, так как командные файлы могут работать только с 32-разрядных целых чисел , Возможно, я мог бы использовать что-то вроде VBS, но это решение, с которым я сейчас работаю.

Мне нужно, чтобы программа была автономной, поэтому она должна статически ссылаться на библиотеки. Я смог получить размер от ~ 570kb до ~ 148kb, заменив все команды coutprintf, но мне интересно, что еще я могу сделать, чтобы уменьшить размер файла.

Я компиляция это с MiniGW 4.6, и это моя команда компиляции на данный момент:

g++ -Os -s -static bytemath.cpp -o bytemath.exe

Что еще я могу сделать, чтобы уменьшить размер файла, не слишком много коды переписывать?

Спасибо.

EDIT

Две большие вкладчики избавлялись от <iostream> и <string>, что я был в состоянии сделать, заменив все мои cout команды с printf и заменить мои сравнения строк с голец * сравнение. Для символов мне нужно было получить доступ к 0-му элементу массива и сравнить его с символом в одинарных кавычках, а не с двойными кавычками (т. Е. if (myinput[0]=='P') {, а не if (myinput=="P") {).

Еще раз спасибо всем! 570kb до 18kb, работает для меня!

+0

Вам действительно не нужен весь вызов printf, который у вас есть. Используйте ваши операторы if для вычисления значений, которые вы хотите вывести, а затем на конце вывода с одним printf. – andre

+0

Я сделал это так, потому что иногда я выводил «длинный длинный», а иногда я выводил «float». Прошло некоторое время с тех пор, как я использовал C++, но для меня это было проще.Используя приведенный ниже совет, чтобы заменить все экземпляры 'string' на' char * ', работал, но я бы предположил, что это тоже поможет, но время, которое потребуется для исправления, не приведет к экономии пространства для этого проекта (теперь это до 18 КБ). Спасибо за отзыв, хотя! – romellem

ответ

2

Просто угадайте, но: удалите строки и замените их перечислениями и/или символом char *. В основном вы используете такие строки, как перечисления, и просто, если на входных символах вы можете получить перечисления.

+0

Я мог бы это сделать. Тем не менее, я не знаком с перечислениями. Это правда, что все, что я использую для строк, это сравнения в выражениях 'if', и я только когда-либо смотрю на 1 символ. Этот инструмент будет использоваться только мной для определенной цели, поэтому мне не нужно много проверки ошибок и тому подобное при вводе аргументов. Я буду играть с обычным символом * и посмотреть, смогу ли я сделать сравнения таким образом. – romellem

+0

Да, я не уверен, что мог бы сделать прямой поиск и замену, но я думаю, что я просто заменил каждый экземпляр 'string' на' char * 'и избавился от' #include ' и уменьшил его до 18kb. Достаточно хорошо для меня! Спасибо за совет. – romellem

+0

Ahhh nevermind, программа не работает сейчас. Я не думаю, что могу сделать 'if (myinput ==" A ")', если тип myinput - 'char *'. Хорошо, мне нужно выяснить, как делать сравнения. Спасибо, я на правильном пути. – romellem

0

Если вы закончили отладку, вы можете добавить '-s' в свою команду компилятора. '-s' означает разделение всех символов. Чтобы разбить или изменить таблицу символов, прикрепленную к выходу ассемблера, и редактор ссылок может сэкономить место после отладки программы, а также будет ограничено динамически связанным символом

Кроме того, попробуйте передать std :: string по реф, а не по значению изменения inputAdjust(const string myinput) к inputAdjust(const string& myinput) Это может помочь уменьшить размер бинарного кода, но это позволит избежать выделения динамической памяти во время выполнения.

+0

Прошло много времени с тех пор, как я сделал что-либо с C++, но я не думаю, что делаю отладки. Я просто компилирую этот .cpp-файл с помощью команды g ++, включенной в мой комментарий. Я должен сначала запустить (например, сделать файл .a), а затем запустить компилятор? – romellem

+0

У вас уже есть команда '-s' в вашей команде компиляции (предполагая, что она делает то же самое для mingw). – dornhege

+0

Извините, я не видел этого «-s»; [Ссылка] (http://en.wikipedia.org/wiki/UPX) – xKommando

Смежные вопросы