C预处理器-在编译时将元素添加到结构

时间:2018-07-30 00:23:23

标签: c c-preprocessor

我正在尝试一种在编译时将元素添加到结构中的方法,但是要在另一个文件中定义它。例如:

defA.h:

  def add_card
    if current_user.stripe_id.blank?
     customer = Stripe::Customer.create(
      email: current_user.email
  )
     current_user.stripe_id = customer.id
     current_user.save
     customer.sources.create(source: params[:stripeToken])
    else
     customer = Stripe::Customer.retrieve(current_user.stripe_id)
    customer.source = params[:stripeToken]
    customer.save
   end
    flash[:notice] = "Your card is saved."
    redirect_to payment_method_path
    rescue Stripe::CardError => e
    flash[:alert] = e.message
    redirect_to payment_method_path
end

otherfile.c:

typedef struct A {
    int element1;
    int element2;
} A;

会导致:

#include "defA.h"

typedef struct B {
    int element1;
} B;

ADD_ELEMENT_TO(A, B, element3)

有人能想到实现这一目标或类似目标的方法吗?我希望能够通过选择编译struct A { int element1; int element2; B element3; }; 或不编译其余版本来控制它。

1 个答案:

答案 0 :(得分:2)

任何使用C预处理器功能的解决方案都会在声明结构的地方弄得一团糟。例如:

主要来源/标题:

#include "SpecialSauce.h"
…
typedef struct A {
    int element1;
    int element2;
    SpecialStuff
} A;

如果客户刚刚购买了基本软件,则SpecialSauce.h包含:

#define SpecialStuff

如果客户支付额外费用,SpecialSauce.h包含:

#define SpecialStuff int element3;

当然,根据所使用的软件版本,将需要使用或不使用element3的代码。

所有这些都可以通过预处理器指令进行控制,并且通过给予适当的注意,通常可以使它不会太混乱。但是商业压力通常会阻止这种情况,并导致软件变得更加混乱,并且维护被忽略。因此,这类纠缠将变得丑陋且昂贵。

另一种选择是保留主源文件,并使用它们来生成具有选定选项的源文件。仅将生成的源文件提供给客户,并且他们不会具有难看的预处理条件。但是,这需要软件来处理主源文件,而主文件本身必须维护,并且主源文件仍必须具有某种条件,由于它们在您的控制之下,因此您可能会保持良好状态,但是,现实世界中的软件又有变得混乱的趋势。