윈도우 환경에  MinGW(http://www.mingw.org/) 와 MSYS 설치하기


무료로 쓰는 C/C++ 컴파일러를 설치하기 위해서
윈도우에 cygwin을 설치한다는 것은 좀 무겁다는 생각이 든다.
이럴 때는 MinGW와 MSYS를 설치하면 간단한 C/C++ 개발 환경이 구축된다.

MinGW는 윈도우용 GCC Compiler Toolchain이고,
MSYS(Minal SYStem)로 윈도우에서 리눅스 쉘(Linux Shell)과 Binutils 환경을 제공한다.


  1. MinGW 다운로드
        - 자세한 설치 방법은 HOWTO Install the MinGW (GCC) Compiler를 참조

  2. MSYS 다운로드
        - 자세한 설치 방법은 MSYS를 참조

  3. MinGW/bin, MSYS/1.0/bin 디렉토리를 환경변수의 PATH에 등록한다.
        - 만약 PATH를 잡지 않고 MSYS를 먼저 실행하였다면,

                  $  export PATH=/c/MinGW/bin:/c/msys/1.0/bin:$PATH
 
          하면 된다.

          설치 후 컴파일 테스트

                   $ gcc -o hello hello.c

                   $ g++ -o hello2 hello2.cpp

                   $ g++ rpnSTL rpnSTL.cpp


[ STL을 이용하는 C++ 예제 소스:  rpnSTL.cpp ]
// stl/rpnSTL.cpp -- RPN (Reverse Polish Notation) Calculator
//
//  Modified by PH Kim, 2009-02-08
//
//  Which are different from the original source rpn.cpp ?
//
//      1. double instead of int
//      2. negative value possible
//      3. support the power operator ^
//      4. etc
//
//  Compile:
//      [Borland C++ 5.5.1]  bcc32 rpnSTL.cpp
//        [Visual C++ 2008]  cl /EHsc rpnSTL.cpp
//                [GNU C++]  g++ rpnSTL.cpp
//
//  Execute:  rpnSTL
//            ./rpnSTL
//
// Original from:
//    http://www.fredosaurus.com/notes-cpp/examples/rpn/rpn.html
// ---------------------------------------------------------
// stl/rpn.cpp -- RPN (Reverse Polish Notation) Calculator
// Fred Swartz 2001-12-05, 2002-09-27
// ---------------------------------------------------------
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <stdexcept>
using namespace std;
//--- prototypes
double pop(vector<double>& stk);
void printVector(vector<double>& stk);
void clearVector(vector<double>& stk);
void printUsage();
//============================================================= main
int main() {
    vector<double> opndStack; // vector used as operand stack
    string token;          // to read number or operator
    cout << "RPN Calculator" << endl;
    printUsage();
    while (cin >> token) {
        if (isdigit(token[0]) || (token.length() > 1 && (token[0] == '-' || token[0] == '+') && isdigit(token[1]))) { // if first is digit, it's number.
            opndStack.push_back(atof(token.c_str())); // convert, push
            printVector(opndStack);
           
        } else { // If it's not a number, assume it's an operator
            double left, right;  //  used by some operators as temps
            switch (token[0]) {  // assume operators are one char
              case '+': opndStack.push_back(pop(opndStack) + pop(opndStack));
                        break;
              case '-': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left - right);
                        break;
              case '*': opndStack.push_back(pop(opndStack) * pop(opndStack));
                        break;
              case '/': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left / right);
                        break;
              case '^': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(pow(left, right));
                        break;
              case '=':
              case 'p':
                        break;
              case 'c':
                        clearVector(opndStack);
                        break;
              case 'q':
                        cout << "Quit" << endl;
                        exit(0);
                        break;
              case 'h':
                        printUsage();
                        break;
              default:  throw domain_error("Undefined operator");
            }
            printVector(opndStack);
            if (!opndStack.empty())
                cout << "    (" << token[0] << ") Top value: " << opndStack.back() << endl;
        }
    }
    return 0;
}//end main
//============================================================== pop
   // This utility function checks stack for underflow
   // and pops (removes and returns) last element.
double pop(vector<double>& stk) {
    if (stk.empty()) {
        throw underflow_error("Stack underflow.");
    }
    double result = stk.back();
    stk.pop_back();
    return result;
}//end pop
double peek(vector<double>& stk) {
    if (stk.empty()) {
        throw underflow_error("Stack underflow.");
    }
    return stk.back();
}//end pop
void printVector(vector<double>& stk) {
    int n = stk.size();
    cout << "[";
    for (int i = 0; i < n; i++) {
       cout << stk[i];
       if (i < n - 1)
           cout <<", ";
    }
    cout << "]" << endl;
}//end printVector
void clearVector(vector<double>& stk) {
    while (!stk.empty()) {
       stk.erase(stk.begin());
       // stk.pop_back();
    }
}//end clearVector
void printUsage() {
    cout << "  +,-,*,/,^: opr,  =,p: show top,  c: clear stack,  q: quit,  h: help" << endl;
}//end printVector
 
/*
// stl/rpn.cpp -- RPN (Reverse Polish Notation) Calculator
// Fred Swartz 2001-12-05, 2002-09-27
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
using namespace std;
int pop(vector<int>& stk);  //--- prototype to pop stack
//============================================================= main
int main() {
    vector<int> opndStack; // vector used as operand stack
    string token;          // to read number or operator
    while (cin >> token) {
        if (isdigit(token[0])) { // if first is digit, it's number.
            opndStack.push_back(atoi(token.c_str())); // convert, push
           
        } else { // If it's not a number, assume it's an operator
            int left, right;  //  used by some operators as temps
            switch (token[0]) {  // assume operators are one char
              case '+': opndStack.push_back(pop(opndStack) + pop(opndStack));
                        break;
              case '-': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left - right);
                        break;
              case '*': opndStack.push_back(pop(opndStack) * pop(opndStack));
                        break;
              case '/': right = pop(opndStack); // get right operand
                        left  = pop(opndStack); // get left operand
                        opndStack.push_back(left / right);
                        break;
              default:  throw domain_error("Undefined operator");
            }
            cout << "Result: " << opndStack.back() << endl;
        }
    }
    return 0;
}//end main
//============================================================== pop
   // This utility function checks stack for underflow
   // and pops (removes and returns) last element.
int pop(vector<int>& stk) {
    if (stk.empty()) {
        throw underflow_error("Stack underflow.");
    }
    int result = stk.back();
    stk.pop_back();
    return result;
}//end pop
*/



크리에이티브 커먼즈 라이선스
Creative Commons License


'소개와 설치 > C++' 카테고리의 다른 글

무료로 쓰는 Borland C/C++ 컴파일러  (0) 2009.02.07
ANSI/ISO 표준 C++ 라이브러리와 STL  (0) 2008.03.21
Posted by Scripter
,

What is D?

소개와 설치/D 2009. 2. 8. 20:57
D 언어는 최초의 C++ 네이티브 컴파일러를 만들었다고 알려진 월터 브라이트(Walter Bright)가 만든 언어로, C++의 많은 장점을 바탕으로 기타 언어(자바, C#, Eiffel 등)들의 장점들과 섞어 만들었다. 이 언어의 이름은 처음에는 Mars 프로그래밍 언어였지만 친구가 D라고 계속 불러 결국 D가 되었다는 허무한 사연이 있다. D 언어의 1.0 버전은 2007년 1월 2일에 나왔고, 현재 D 1.0 최신 버전은 2009년 1월 2일에 나온 1.039 버전이다.
대폭 향상된 D 2.0 은 현재 알파 버전으로서 최신 버전은 2009년 1월 2일에 나온 D 2.023 이다.


1. D 언어 소개(한글 문서):
    http://www.ibm.com/developerworks/kr/library/opendw/20070626/

2. 위키피디아에서 소개하는 D 언어:
    
http://en.wikipedia.org/wiki/D_language

3. D 언어 1.0 스펙 PDF 문서:
     http://www.prowiki.org/upload/duser/spec_DMD_1.00.pdf

4. 2007년 4월 23일~25일 시애틀에서 있었던 D 언어 컨퍼런스:
    http://d.puremagic.com/conference2007/
     (이 곳에는 행사 때의 사진, 발표자의 ppt 자료, 발표 동영상 등이 있다.)


5. 국내에서 개발된 한글 출력 잘하는 (D 2.0 기반) Visual D:
    http://www.woojinnet.net/visuald/




What is D?

D is a general purpose systems and applications programming language. It is a higher level language than C++, but retains the ability to write high performance code and interface directly with the operating system API's and with hardware. D is well suited to writing medium to large scale million line programs with teams of developers. D is easy to learn, provides many capabilities to aid the programmer, and is well suited to aggressive compiler optimization technology. D Man

D is not a scripting language, nor an interpreted language. It doesn't come with a VM, a religion, or an overriding philosophy. It's a practical language for practical programmers who need to get the job done quickly, reliably, and leave behind maintainable, easy to understand code.

D is the culmination of decades of experience implementing compilers for many diverse languages, and attempting to construct large projects using those languages. D draws inspiration from those other languages (most especially C++) and tempers it with experience and real world practicality.

Why D?

Why, indeed. Who needs another programming language?

The software industry has come a long way since the C language was invented. Many new concepts were added to the language with C++, but backwards compatibility with C was maintained, including compatibility with nearly all the weaknesses of the original design. There have been many attempts to fix those weaknesses, but the compatibility issue frustrates it. Meanwhile, both C and C++ undergo a constant accretion of new features. These new features must be carefully fitted into the existing structure without requiring rewriting old code. The end result is very complicated - the C standard is nearly 500 pages, and the C++ standard is about 750 pages! C++ is a difficult and costly language to implement, resulting in implementation variations that make it frustrating to write fully portable C++ code.

C++ programmers tend to program in particular islands of the language, i.e. getting very proficient using certain features while avoiding other feature sets. While the code is usually portable from compiler to compiler, it can be hard to port it from programmer to programmer. A great strength of C++ is that it can support many radically different styles of programming - but in long term use, the overlapping and contradictory styles are a hindrance.

C++ implements things like resizable arrays and string concatenation as part of the standard library, not as part of the core language. Not being part of the core language has several suboptimal consequences.

Can the power and capability of C++ be extracted, redesigned, and recast into a language that is simple, orthogonal, and practical? Can it all be put into a package that is easy for compiler writers to correctly implement, and which enables compilers to efficiently generate aggressively optimized code?

Modern compiler technology has progressed to the point where language features for the purpose of compensating for primitive compiler technology can be omitted. (An example of this would be the 'register' keyword in C, a more subtle example is the macro preprocessor in C.) We can rely on modern compiler optimization technology to not need language features necessary to get acceptable code quality out of primitive compilers.

Major Goals of D

  • Reduce software development costs by at least 10% by adding in proven productivity enhancing features and by adjusting language features so that common, time-consuming bugs are eliminated from the start.
  • Make it easier to write code that is portable from compiler to compiler, machine to machine, and operating system to operating system.
  • Support multi-paradigm programming, i.e. at a minimum support imperative, structured, object oriented, and generic programming paradigms.
  • Have a short learning curve for programmers comfortable with programming in C or C++.
  • Provide low level bare metal access as required.
  • Make D substantially easier to implement a compiler for than C++.
  • Be compatible with the local C application binary interface.
  • Have a context-free grammar.
  • Easily support writing internationalized applications.
  • Incorporate Contract Programming and unit testing methodology.
  • Be able to build lightweight, standalone programs.
  • Reduce the costs of creating documentation.

Features To Keep From C/C++

The general look of D is like C and C++. This makes it easier to learn and port code to D. Transitioning from C/C++ to D should feel natural. The programmer will not have to learn an entirely new way of doing things.

Using D will not mean that the programmer will become restricted to a specialized runtime vm (virtual machine) like the Java vm or the Smalltalk vm. There is no D vm, it's a straightforward compiler that generates linkable object files. D connects to the operating system just like C does. The usual familiar tools like make will fit right in with D development.

  • The general look and feel of C/C++ is maintained. It uses the same algebraic syntax, most of the same expression and statement forms, and the general layout.
  • D programs can be written either in C style function-and-data, C++ style object-oriented, C++ style template metaprogramming, or any mix of the three.
  • The compile/link/debug development model is carried forward, although nothing precludes D from being compiled into bytecode and interpreted.
  • Exception handling. More and more experience with exception handling shows it to be a superior way to handle errors than the C traditional method of using error codes and errno globals.
  • Runtime Type Identification. This is partially implemented in C++; in D it is taken to its next logical step. Fully supporting it enables better garbage collection, better debugger support, more automated persistence, etc.
  • D maintains function link compatibility with the C calling conventions. This makes it possible for D programs to access operating system API's directly. Programmers' knowledge and experience with existing programming API's and paradigms can be carried forward to D with minimal effort.
  • Operator overloading. D programs can overload operators enabling extension of the basic types with user defined types.
  • Template Metaprogramming. Templates are a way to implement generic programming. Other ways include using macros or having a variant data type. Using macros is out. Variants are straightforward, but inefficient and lack type checking. The difficulties with C++ templates are their complexity, they don't fit well into the syntax of the language, all the various rules for conversions and overloading fitted on top of it, etc. D offers a much simpler way of doing templates.
  • RAII (Resource Acquisition Is Initialization). RAII techniques are an essential component of writing reliable software.
  • Down and dirty programming. D retains the ability to do down-and-dirty programming without resorting to referring to external modules compiled in a different language. Sometimes, it's just necessary to coerce a pointer or dip into assembly when doing systems work. D's goal is not to prevent down and dirty programming, but to minimize the need for it in solving routine coding tasks.

Features To Drop

  • C source code compatibility. Extensions to C that maintain source compatibility have already been done (C++ and ObjectiveC). Further work in this area is hampered by so much legacy code it is unlikely that significant improvements can be made.
  • Link compatibility with C++. The C++ runtime object model is just too complicated - properly supporting it would essentially imply making D a full C++ compiler too.
  • The C preprocessor. Macro processing is an easy way to extend a language, adding in faux features that aren't really there (invisible to the symbolic debugger). Conditional compilation, layered with #include text, macros, token concatenation, etc., essentially forms not one language but two merged together with no obvious distinction between them. Even worse (or perhaps for the best) the C preprocessor is a very primitive macro language. It's time to step back, look at what the preprocessor is used for, and design support for those capabilities directly into the language.
  • Multiple inheritance. It's a complex feature of debatable value. It's very difficult to implement in an efficient manner, and compilers are prone to many bugs in implementing it. Nearly all the value of MI can be handled with single inheritance coupled with interfaces and aggregation. What's left does not justify the weight of MI implementation.
  • Namespaces. An attempt to deal with the problems resulting from linking together independently developed pieces of code that have conflicting names. The idea of modules is simpler and works much better.
  • Tag name space. This misfeature of C is where the tag names of structs are in a separate but parallel symbol table. C++ attempted to merge the tag name space with the regular name space, while retaining backward compatibility with legacy C code. The result is needlessly confusing.
  • Forward declarations. C compilers semantically only know about what has lexically preceded the current state. C++ extends this a little, in that class members can rely on forward referenced class members. D takes this to its logical conclusion, forward declarations are no longer necessary at the module level. Functions can be defined in a natural order rather than the typical inside-out order commonly used in C programs to avoid writing forward declarations.
  • Include files. A major cause of slow compiles as each compilation unit must reparse enormous quantities of header files. Include files should be done as importing a symbol table.
  • Trigraphs and digraphs. Unicode is the future.
  • Non-virtual member functions. In C++, a class designer decides in advance if a function is to be virtual or not. Forgetting to retrofit the base class member function to be virtual when the function gets overridden is a common (and very hard to find) coding error. Making all member functions virtual, and letting the compiler decide if there are no overrides and hence can be converted to non-virtual, is much more reliable.
  • Bit fields of arbitrary size. Bit fields are a complex, inefficient feature rarely used.
  • Support for 16 bit computers. No consideration is given in D for mixed near/far pointers and all the machinations necessary to generate good 16 bit code. The D language design assumes at least a 32 bit flat memory space. D will fit smoothly into 64 bit architectures.
  • Mutual dependence of compiler passes. In C++, successfully parsing the source text relies on having a symbol table, and on the various preprocessor commands. This makes it impossible to preparse C++ source, and makes writing code analyzers and syntax directed editors painfully difficult to do correctly.
  • Compiler complexity. Reducing the complexity of an implementation makes it more likely that multiple, correct implementations are available.
  • Dumbed down floating point. If one is using hardware that implements modern floating point, it should be available to the programmer rather than having floating point support dumbed down to the lowest common denominator among machines. In particular, a D implementation must support IEEE 754 arithmetic and if extended precision is available it must be supported.
  • Template overloading of < and > symbols. This choice has caused years of bugs, grief, and confusion for programmers, C++ implementors, and C++ source parsing tool vendors. It makes it impossible to parse C++ code correctly without doing a nearly complete C++ compiler. D uses !( and ) which fit neatly and unambiguously into the grammar.

Who D is For

  • Programmers who routinely use lint or similar code analysis tools to eliminate bugs before the code is even compiled.
  • People who compile with maximum warning levels turned on and who instruct the compiler to treat warnings as errors.
  • Programming managers who are forced to rely on programming style guidelines to avoid common C bugs.
  • Those who decide the promise of C++ object oriented programming is not fulfilled due to the complexity of it.
  • Programmers who enjoy the expressive power of C++ but are frustrated by the need to expend much effort explicitly managing memory and finding pointer bugs.
  • Projects that need built-in testing and verification.
  • Teams who write apps with a million lines of code in it.
  • Programmers who think the language should provide enough features to obviate the continual necessity to manipulate pointers directly.
  • Numerical programmers. D has many features to directly support features needed by numerics programmers, like extended floating point precision, core support for complex and imaginary floating types and defined behavior for NaN's and infinities. (These are added in the new C99 standard, but not in C++.)
  • Programmers who write half their application in scripting langauges like Ruby and Python, and the other half in C++ to speed up the bottlenecks. D has many of the productivity features of Ruby and Python, making it possible to write the entire app in one language.
  • D's lexical analyzer and parser are totally independent of each other and of the semantic analyzer. This means it is easy to write simple tools to manipulate D source perfectly without having to build a full compiler. It also means that source code can be transmitted in tokenized form for specialized applications.

Who D is Not For

  • Realistically, nobody is going to convert million line C or C++ programs into D. Since D does not compile unmodified C/C++ source code, D is not for legacy apps. (However, D supports legacy C API's very well. D can connect directly to any code that exposes a C interface.)
  • As a first programming language - Basic or Java is more suitable for beginners. D makes an excellent second language for intermediate to advanced programmers.
  • Language purists. D is a practical language, and each feature of it is evaluated in that light, rather than by an ideal. For example, D has constructs and semantics that virtually eliminate the need for pointers for ordinary tasks. But pointers are still there, because sometimes the rules need to be broken. Similarly, casts are still there for those times when the typing system needs to be overridden.

Major Features of D

This section lists some of the more interesting features of D in various categories.

Object Oriented Programming

Classes

D's object oriented nature comes from classes. The inheritance model is single inheritance enhanced with interfaces. The class Object sits at the root of the inheritance hierarchy, so all classes implement a common set of functionality. Classes are instantiated by reference, and so complex code to clean up after exceptions is not required.

Operator Overloading

Classes can be crafted that work with existing operators to extend the type system to support new types. An example would be creating a bignumber class and then overloading the +, -, * and / operators to enable using ordinary algebraic syntax with them.

Productivity

Modules

Source files have a one-to-one correspondence with modules. Instead of #include'ing the text of a file of declarations, just import the module. There is no need to worry about multiple imports of the same module, no need to wrapper header files with #ifndef/#endif or #pragma once kludges, etc.

Declaration vs Definition

C++ usually requires that functions and classes be declared twice - the declaration that goes in the .h header file, and the definition that goes in the .c source file. This is an error prone and tedious process. Obviously, the programmer should only need to write it once, and the compiler should then extract the declaration information and make it available for symbolic importing. This is exactly how D works.

Example:

class ABC
{
    int func() { return 7; }
    static int z = 7;
}
int q;

There is no longer a need for a separate definition of member functions, static members, externs, nor for clumsy syntaxes like:

int ABC::func() { return 7; }
int ABC::z = 7;
extern int q;

Note: Of course, in C++, trivial functions like { return 7; } are written inline too, but complex ones are not. In addition, if there are any forward references, the functions need to be prototyped. The following will not work in C++:

class Foo
{
    int foo(Bar *c) { return c->bar(); }
};

class Bar
{
  public:
    int bar() { return 3; }
};

But the equivalent D code will work:

class Foo
{
    int foo(Bar c) { return c.bar; }
}

class Bar
{
    int bar() { return 3; }
}

Whether a D function is inlined or not is determined by the optimizer settings.

Templates

D templates offer a clean way to support generic programming while offering the power of partial specialization. Template classes and template functions are available, along with variadic template arguments and tuples.

Associative Arrays

Associative arrays are arrays with an arbitrary data type as the index rather than being limited to an integer index. In essence, associated arrays are hash tables. Associative arrays make it easy to build fast, efficient, bug-free symbol tables.

Real Typedefs

C and C++ typedefs are really type aliases, as no new type is really introduced. D implements real typedefs, where:

typedef int handle;

really does create a new type handle. Type checking is enforced, and typedefs participate in function overloading. For example:

int foo(int i);
int foo(handle h);

Documentation

Documentation has traditionally been done twice - first there are comments documenting what a function does, and then this gets rewritten into a separate html or man page. And naturally, over time, they'll tend to diverge as the code gets updated and the separate documentation doesn't. Being able to generate the requisite polished documentation directly from the comments embedded in the source will not only cut the time in half needed to prepare documentation, it will make it much easier to keep the documentation in sync with the code. Ddoc is the specification for the D documentation generator. This page was generated by Ddoc, too.

Although third party tools exist to do this for C++, they have some serious shortcomings:

  • It is spectacularly difficult to parse C++ 100% correctly. To do so really requires a full C++ compiler. Third party tools tend to parse only a subset of C++ correctly, so their use will constrain the source code to that subset.
  • Different compilers support different versions of C++ and have different extensions to C++. Third party tools have a problem matching all these variations.
  • Third party tools may not be available for all the desired platforms, and they're necessarily on a different upgrade cycle from the compilers.
  • Having it builtin to the compiler means it is standardized across all D implementations. Having a default one ready to go at all times means it is far more likely to be used.

Functions

D has the expected support for ordinary functions including global functions, overloaded functions, inlining of functions, member functions, virtual functions, function pointers, etc. In addition:

Nested Functions

Functions can be nested within other functions. This is highly useful for code factoring, locality, and function closure techniques.

Function Literals

Anonymous functions can be embedded directly into an expression.

Dynamic Closures

Nested functions and class member functions can be referenced with closures (also called delegates), making generic programming much easier and type safe.

In Out and Inout Parameters

Not only does specifying this help make functions more self-documenting, it eliminates much of the necessity for pointers without sacrificing anything, and it opens up possibilities for more compiler help in finding coding problems.

Such makes it possible for D to directly interface to a wider variety of foreign API's. There would be no need for workarounds like "Interface Definition Languages".

Arrays

C arrays have several faults that can be corrected:

  • Dimension information is not carried around with the array, and so has to be stored and passed separately. The classic example of this are the argc and argv parameters to main(int argc , char *argv []). (In D, main is declared as main(char[][] args ).)
  • Arrays are not first class objects. When an array is passed to a function, it is converted to a pointer, even though the prototype confusingly says it's an array. When this conversion happens, all array type information gets lost.
  • C arrays cannot be resized. This means that even simple aggregates like a stack need to be constructed as a complex class.
  • C arrays cannot be bounds checked, because they don't know what the array bounds are.
  • Arrays are declared with the [] after the identifier. This leads to very clumsy syntax to declare things like a pointer to an array:
    int (*array)[3];
    

    In D, the [] for the array go on the left:

    int[3]* array;		// declares a pointer to an array of 3 ints
    long[] func(int x);	// declares a function returning an array of longs
    

    which is much simpler to understand.

D arrays come in several varieties: pointers, static arrays, dynamic arrays, and associative arrays.

See Arrays.

Strings

String manipulation is so common, and so clumsy in C and C++, that it needs direct support in the language. Modern languages handle string concatenation, copying, etc., and so does D. Strings are a direct consequence of improved array handling.

Resource Management

Automatic Memory Management

D memory allocation is fully garbage collected. Empirical experience suggests that a lot of the complicated features of C++ are necessary in order to manage memory deallocation. With garbage collection, the language gets much simpler.

There's a perception that garbage collection is for lazy, junior programmers. I remember when that was said about C++, after all, there's nothing in C++ that cannot be done in C, or in assembler for that matter.

Garbage collection eliminates the tedious, error prone memory allocation tracking code necessary in C and C++. This not only means much faster development time and lower maintenance costs, but the resulting program frequently runs faster!

Sure, garbage collectors can be used with C++, and I've used them in my own C++ projects. The language isn't friendly to collectors, however, impeding the effectiveness of it. Much of the runtime library code can't be used with collectors.

For a fuller discussion of this, see garbage collection.

Explicit Memory Management

Despite D being a garbage collected language, the new and delete operations can be overridden for particular classes so that a custom allocator can be used.

RAII

RAII is a modern software development technique to manage resource allocation and deallocation. D supports RAII in a controlled, predictable manner that is independent of the garbage collection cycle.

Performance

Lightweight Aggregates

D supports simple C style structs, both for compatibility with C data structures and because they're useful when the full power of classes is overkill.

Inline Assembler

Device drivers, high performance system applications, embedded systems, and specialized code sometimes need to dip into assembly language to get the job done. While D implementations are not required to implement the inline assembler, it is defined and part of the language. Most assembly code needs can be handled with it, obviating the need for separate assemblers or DLL's.

Many D implementations will also support intrinsic functions analogously to C's support of intrinsics for I/O port manipulation, direct access to special floating point operations, etc.

Reliability

A modern language should do all it can to help the programmer flush out bugs in the code. Help can come in many forms; from making it easy to use more robust techniques, to compiler flagging of obviously incorrect code, to runtime checking.

Contracts

Contract Programming (invented by B. Meyer) is a revolutionary technique to aid in ensuring the correctness of programs. D's version of DBC includes function preconditions, function postconditions, class invariants, and assert contracts. See Contracts for D's implementation.

Unit Tests

Unit tests can be added to a class, such that they are automatically run upon program startup. This aids in verifying, in every build, that class implementations weren't inadvertently broken. The unit tests form part of the source code for a class. Creating them becomes a natural part of the class development process, as opposed to throwing the finished code over the wall to the testing group.

Unit tests can be done in other languages, but the result is kludgy and the languages just aren't accommodating of the concept. Unit testing is a main feature of D. For library functions it works out great, serving both to guarantee that the functions actually work and to illustrate how to use the functions.

Consider the many C++ library and application code bases out there for download on the web. How much of it comes with *any* verification tests at all, let alone unit testing? Less than 1%? The usual practice is if it compiles, we assume it works. And we wonder if the warnings the compiler spits out in the process are real bugs or just nattering about nits.

Along with Contract Programming, unit testing makes D far and away the best language for writing reliable, robust systems applications. Unit testing also gives us a quick-and-dirty estimate of the quality of some unknown piece of D code dropped in our laps - if it has no unit tests and no contracts, it's unacceptable.

Debug Attributes and Statements

Now debug is part of the syntax of the language. The code can be enabled or disabled at compile time, without the use of macros or preprocessing commands. The debug syntax enables a consistent, portable, and understandable recognition that real source code needs to be able to generate both debug compilations and release compilations.

Exception Handling

The superior try-catch-finally model is used rather than just try-catch. There's no need to create dummy objects just to have the destructor implement the finally semantics.

Synchronization

Multithreaded programming is becoming more and more mainstream, and D provides primitives to build multithreaded programs with. Synchronization can be done at either the method or the object level.

synchronized int func() { ... }

Synchronized functions allow only one thread at a time to be executing that function.

The synchronize statement puts a mutex around a block of statements, controlling access either by object or globally.

Support for Robust Techniques

  • Dynamic arrays instead of pointers
  • Reference variables instead of pointers
  • Reference objects instead of pointers
  • Garbage collection instead of explicit memory management
  • Built-in primitives for thread synchronization
  • No macros to inadvertently slam code
  • Inline functions instead of macros
  • Vastly reduced need for pointers
  • Integral type sizes are explicit
  • No more uncertainty about the signed-ness of chars
  • No need to duplicate declarations in source and header files.
  • Explicit parsing support for adding in debug code.

Compile Time Checks

  • Stronger type checking
  • No empty ; for loop bodies
  • Assignments do not yield boolean results
  • Deprecating of obsolete API's

Runtime Checking

  • assert() expressions
  • array bounds checking
  • undefined case in switch exception
  • out of memory exception
  • In, out, and class invariant Contract Programming support

Compatibility

Operator precedence and evaluation rules

D retains C operators and their precedence rules, order of evaluation rules, and promotion rules. This avoids subtle bugs that might arise from being so used to the way C does things that one has a great deal of trouble finding bugs due to different semantics.

Direct Access to C API's

Not only does D have data types that correspond to C types, it provides direct access to C functions. There is no need to write wrapper functions, parameter swizzlers, nor code to copy aggregate members one by one.

Support for all C data types

Making it possible to interface to any C API or existing C library code. This support includes structs, unions, enums, pointers, and all C99 types. D includes the capability to set the alignment of struct members to ensure compatibility with externally imposed data formats.

OS Exception Handling

D's exception handling mechanism will connect to the way the underlying operating system handles exceptions in an application.

Uses Existing Tools

D produces code in standard object file format, enabling the use of standard assemblers, linkers, debuggers, profilers, exe compressors, and other analyzers, as well as linking to code written in other languages.

Project Management

Versioning

D provides built-in support for generation of multiple versions of a program from the same text. It replaces the C preprocessor #if/#endif technique.

Deprecation

As code evolves over time, some old library code gets replaced with newer, better versions. The old versions must be available to support legacy code, but they can be marked as deprecated. Code that uses deprecated versions will be normally flagged as illegal, but would be allowed by a compiler switch. This will make it easy for maintenance programmers to identify any dependence on deprecated features.

Sample D Program (sieve.d)

/* Sieve of Eratosthenes prime numbers */

import std.stdio;

bool[8191] flags;
 
int main()
{   int i, count, prime, k, iter;

    writefln("10 iterations");
    for (iter = 1; iter <= 10; iter++)
    {	count = 0;
	flags[] = 1;
	for (i = 0; i < flags.length; i++)
	{   if (flags[i])
	    {	prime = i + i + 3;
		k = i + prime;
		while (k < flags.length)
		{
		    flags[k] = 0;
		    k += prime;
		}
		count += 1;
	    }
	}
    }
    writefln("%d primes", count);
    return 0;
}


'소개와 설치 > D' 카테고리의 다른 글

D 2.0 에서 대폭 달라진 Array  (0) 2009.02.09
Posted by Scripter
,



1. Borland C 5.5 Free 다운로드 (약 8.5 메가)

http://www.codegear.com/downloads/free/cppbuilder


2. 명령행 컴파일러 Borland C 5.5 설치와 테스트

(1) http://csjava.occ.cccd.edu/~gilberts/bcc55.html
(2) http://www.geocities.com/thestarman3/C/bcpp55.html
(3) http://www.cprogramming.com/borland.html


 



 

Posted by Scripter
,

OOP의 개념(Concepts of OOP):

  • 객체(Objects)
  • 클래스(Classes)
  • 데이터 추상화와 캡슐화(Data Abstraction and Encapsulation)
  • 상속(Inheritance)
  • 다형성(Polymorphism )

 

객체지향 프로그래밍의 간략 소개(Briefly on Concepts):

객체Objects(객체)

객체(Objects)는 객체지향 체계에서 기본적인 런타임 실체이다.
프로그래밍 문제는 객체 내의 소통 및 타 객체간 소통이라고 볼 수 있다.
프로그램이 실행되면 객체들은 서로 메세지를 주고 받으며 상호작용한다. 
다른 객체들은 상대방의 데이터나 코드를 잘 알지 못하더라도 상호작용한다.


클래스(Classes)


클래스(class)는 유사 타입의 객체들의 집합이다.
일단 한 클래스가 정의 되면, 그 클래스에 속하는 객체는 무제한 생성될 수 있다.


테이터 추상화와 캡슐화(Data Abstraction and Encapsulation)

추상화(Abstraction)란 배경의 상세나 설명을 포함하지 않고도 근본적 특징을 표현하는 행위를 일컫는다. 클래스는 추상화 개념을 사용하며 추상적인 속성들로 정의되기도 한다.

데이터와 함수를 하나의 단위(클래스)에 저장하는 것은 캡슐화(encapsulation)이다. 외부 세계는 이 데이터에 직접 접근할 수 없으며, 오직 그 클래스 안에 데이터와 함께 저장된 함수만이 접근할 수 있다. 이런(같은 클래스안에 데이터와 저장된) 함수를 메소드(method)라고 한다.


상속(Inheritance)

상속(Inheritance)은 객체가 다른 클래스의 객체의 특징을 물려받을 수 있게 하는 일종의 절차이다. 객체지향 프로그래밍(OOP)에서 상속(inheritance)은 기존의 클래스를 수정하지 않고도 특징을 더 추가할 수 있게 하는 등의 재사용성을 제공한다. 이는 기존의 클래스로 부터 새 클래스를 파생시킴으로서 이루어진다. 파생된 새 클랙스는 (자신과 부모) 클래스의 결합된 특징을 모두 갖는다.


다형성(Polymorphism)

다형성(Polymorphism)이란 한 가지 형태보다 더 많은 형태를 가질 수 있음을 의미한다.
한 동작이 다른 인스턴스에 다른 행동을 일으키게 하는 것이 가능하다. 그 행동은 그 동작에 사용되는 데이터 타입에 의존한다. 다형성은 상속을 구현하는데에 광범위하게 사용된다.


OOP의 이점(Advantages of OOP) 

객체지향 프로그래밍(OOP) 관습적인 접근을 넘어 다음과 같은 이점을 갖고 있다. 

  • OOP는 구체적인 상세 구현을 감추고 그 단위(unit)만 정의한 인터페이스를 갖는 추상적 데이터 타입을 정의하기에 편한 (프로그램을 위한) 모듈화 구조를 제공한다.
  • OOOP는 새 객체가 기존의 것과 다소 다르게 생성되도록 위해 기존의 소스 코드를 관리 수정하기를 쉽게 해준다.
  • OOP는 제공되는 소프트웨어 구성요소가 프로그래머에 의해서 쉽게 수용되고 수정될 수 있는 코드 라이브러리를 위한 좋은 프레임웍을 제공한다.

 

Posted by Scripter
,

Io 언어는2002년 3월 7일 Steve Dekorte 에 의하여 만들어진 프로그래밍 언어이다.

Io는 스몰토크(Smalltalk), 셀프(Self), 루아(Lua), 리스프(LISP), 액트1(Act1), 뉴튼스크립트(NewtonScript) 언어들로 부터 영향을 받은, 프로토타입 기반순수 객체지향 언어이다. Io의 프로토타입 모델은 셀프, 뉴튼스크립트의 것과 비슷하며 객체와 클래스 사이의 구별을 뚜렷이 한다. 스몰토크에서 처럼, Io에서도 모든 것이 객체이다. 또 Io의 타이핑은 통적이다. 리스프 처럼, Io 언어에는 구문이 없으며, 흐름 제어는 함수를 이용하며, Io 프로그램은 모두 데이터 트리이다. Io는 현대의 프로그램 언어에서 드물게 사용되는 항속성을 위하여 액터(actor)를 이용한다.

Io의 뚜렷한 특징은 효율성, 최소화, 외부로의 개방성이다.
Io는 작고 이식가능한 가상기계 위에서 실행된다.


위키피디아의 Io 소개: http://en.wikipedia.org/wiki/Io_programming_language
위키북 Io 초보자 길잡이: http://en.wikibooks.org/wiki/Io_Programming/Beginner's_Guide/About
Io 홈페이지:  http://iolanguage.com/
Io 프로그램 노트: http://iota.flowsnake.org/
한국 Io 사용자 모임:  http://iolanguage.kr/
초고속 Io 튜토리얼:  http://justhing.dahlia.kr/io-tutorial-for-programmer/




Io 설치  후 간단한 테스트

* 먼저 Io 가 설치된 곳 아래의 bin 폴더를 환경변수 PATH에 잡아준다.

실행> io
20080107
Io> "Hello, world!" print
Hello, world!==> Hello, world!
Io> "Hello, world!" println
Hello, world!
==> Hello, world!
Io> ^Z


* 이번에는 다음 내용의 텍스트 파일을 생성한다. (io 스크립트 소스파일)

       # Filename: hello.io
       greeting := "Hello"
       "#{greeting}, world!" interpolate println


실행> io hello.io
Hello, world!

Posted by Scripter
,
Posted by Scripter
,

국제 표준 기구(International Standards Organization, ISO)와 미국 국가 표준 기관(American National Standards Institute, ANSI)은 C++ 프로그래밍 언어의 표준화 작업을 마쳤다(표준 번호: ISO/IEC 14882). 이 표준화 과정에서 가장 중요한 부분의 하나가 바로 「표준 C++ 라이브러리(standard C++ library)」이며, 이 라이브러리는 많은 양의 클래스와 함수들을 제공하고 있다.

ANSI/ISO 표준 C++ 라이브러리는 다음을 포함하고 있다.

  • 많은 양의 데이터 구조와 알고리듬. 특히 이 부분만 따로 「표준 템플릿 라이브러리(standard template library, STL)」라고 부른다.
  • 입출력 스트림
  • locale 기능
  • string 템플릿 클래스
  • complex 템플릿 클래스
  • numeric_limits 템플릿 클래스
  • 메모리 관리 기능
  • Language support 기능
  • 예외 처리(exception handling) 기능
  • 수치 배열용으로 최적화된 valarray 클래스


참고: Standard C++ Library 관련 자료


Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

Posted by Scripter
,