Как разбить C-функции без увеличения размера стека - PullRequest
0 голосов
/ 10 июня 2018

Работая в области разработки встраиваемых систем, я часто сталкиваюсь с Legacy Code, где кто-то написал ISR, состоящий из огромных if / else-Jungle, иногда охватывающих несколько экранов.Теперь, пытаясь быть хорошим программистом, я пытаюсь реорганизовать функцию, используя изученные мной парадигмы, одна из которых звучит так: «Функция должна делать только одну вещь».

Поэтому я разбиваю функцию на несколькостатическая подфункция, которая имеет описательные имена и инкапсулирует переменные.Но поскольку я работаю над встроенным устройством, мне нужно учитывать размер стека и количество переходов (особенно в ISR, который может вызываться часто и сам может быть прерван чем-то другим).

Теперь,Конечно, большинство (или даже все) компиляторы могут быть вынуждены встроить функцию (как __always_inline делает с gcc).Но даже это увеличивает размер стека, если мне нужно передать параметры (они не обязательно оптимизируются), даже если это всего лишь несколько байтов на параметр.

Теперь для моего реального вопроса: Есть лиспособ не увеличивать размер стека при разбивании функций в C?

РЕДАКТИРОВАТЬ: Чтобы прояснить мой вопрос: Вот пример некоторого кода, где я только что сдвинул некоторые изкод для inline-функций.

Использование статического стека составляет 144 без встроенных функций и 160 с встроенными функциями.

Оригинал:

#include <stdio.h>
#include <string.h>

int main(){

  char inputString[100];
  scanf("%s",inputString);

  static char delimiterArray[] = {' ','+','-','/','*','='};
  for(int i = 0; i<sizeof(inputString); i++){
    printf("%c",inputString[i]);

    char* inputChar = inputString + i;
    for(int j = 0; j<sizeof(delimiterArray);j++){
      if( *inputChar == delimiterArray[j]){
        printf("DELIMITER: %c",delimiterArray[j]);
      }
      if(inputString[i] == '\0'){
        printf("\nNuberOfChars: %d\n",i);
        break;
      }
    }
  }

  return 0;
}

С встроенными функциями:

#include <stdio.h>
#include <string.h>

static inline void checkForDelimiters(char* inputChar)__attribute__((always_inline));
static inline void decomposeString(char* inputString)__attribute__((always_inline));

int main(){

  char inputString[100];
  scanf("%s",inputString);
  decomposeString(inputString);

  return 0;
}

static void checkForDelimiters(char* inputChar){
  static char delimiterArray[] = {' ','+','-','/','*','='};
  for(int j = 0; j<sizeof(delimiterArray);j++){
    if(*inputChar == delimiterArray[j]){
      printf("DELIMITER: %c",delimiterArray[j]);
    }
  }
}

static void decomposeString(char* inputString){

  for(int i = 0; i<sizeof(inputString); i++){
    printf("%c",inputString[i]);
    checkForDelimiters(inputString+i);

    if(inputString[i] == '\0'){
      printf("\nNuberOfChars: %d\n",i);
      break;
    }
  }
}
...