社区
网络编程
帖子详情
10022Socket not bound, invalid address or listen is not invoked prior to accept
bywind1980
2005-03-24 07:17:22
求助。从网页中调用activeX控件,作为socket通讯的客户端,本地机器上运行服务端程序,两者进行socket通讯。开始,通讯正常,但是多次连续进行通讯操作之后,就出现标题所示的错误,请教各位。
...全文
154
4
打赏
收藏
10022Socket not bound, invalid address or listen is not invoked prior to accept
求助。从网页中调用activeX控件,作为socket通讯的客户端,本地机器上运行服务端程序,两者进行socket通讯。开始,通讯正常,但是多次连续进行通讯操作之后,就出现标题所示的错误,请教各位。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
labixiaoxing
2005-04-06
打赏
举报
回复
做一个timer,每隔1分钟踢除不传送数据的端口。客户再连接会自动分配的。
timer:
dim winsocklastsendtime
发送时:
winsocklastsendtime(index)=timer
for i=1 to winsock1.count
if timer-winsocklastsendtime(i)>=60 then
winsock1(i).close
end if
next
●●●●●我是新手,我要提高,把分给我,谢谢!◆◆◆◆◆◆◆◆
●你好,我好大家好!希望我能成为你某方面的专家!谢谢支持!●
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
zyg0
2005-04-01
打赏
举报
回复
1个专门负责坚挺,一个专门和客户端accept
bywind1980
2005-04-01
打赏
举报
回复
有没有人知道阿
bywind1980
2005-03-25
打赏
举报
回复
用netstat命令发现有7,8个端口都被我的程序占用,处于time_wait状态,请问如何释放被占用的端口阿
Google C++ Style Guide(Google C++编程规范)高清PDF
Table of Cont
en
ts Header Files The #define Guard Header File Dep
en
d
en
cies Inline Functions The -inl.h Files Function Parameter Ordering Names and Order of Includes Scoping Namespaces Nested Classes Nonmember, Static Member, and Global Functions Local Variables Static and Global Variables Classes Doing Work in Constructors Default Constructors Explicit Constructors Copy Constructors Structs vs. Classes Inheritance Multiple Inheritance Interfaces Operator Overloading Access Control Declaration Order Write Short Functions Google-Specific Magic Smart Pointers cpplint Other C++ Features Refer
en
ce Argum
en
ts Function Overloading Default Argum
en
ts Variable-L
en
gth Arrays and alloca() Fri
en
ds Exceptions Run-Time Type Information (RTTI) Casting Streams Preincrem
en
t and Predecrem
en
t Use of const Integer Types 64-bit Portability Preprocessor Macros 0 and NULL sizeof Boost C++0x Naming G
en
eral Naming Rules File Names Type Names Variable Names Constant Names Function Names Namespace Names
En
umerator Names Macro Names Exceptions to Naming Rules Comm
en
ts Comm
en
t Style File Comm
en
ts Class Comm
en
ts Function Comm
en
ts Variable Comm
en
ts Implem
en
tation Comm
en
ts Punctuation, Spelling and Grammar TODO Comm
en
ts Deprecation Comm
en
ts Formatting Line L
en
gth Non-ASCII Characters Spaces vs. Tabs Function Declarations and Definitions Function Calls Conditionals Loops and Switch Statem
en
ts Pointer and Refer
en
ce Expressions Boolean Expressions Return Values Variable and Array Initialization Preprocessor Directives Class Format Constructor Initializer
List
s Namespace Formatting Horizontal Whitespace Vertical Whitespace Exceptions to the Rules Existing Non-conformant Code Windows Code Important Note Displaying Hidd
en
Details in this Guide link ▶This style guide contains many details that are initially hidd
en
from view. They are marked by the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear below. Hooray! Now you know you can expand points to get more details. Alternatively, there's an "expand all" at the top of this docum
en
t. Background C++ is the main developm
en
t language used by many of Google's op
en
-source projects. As every C++ programmer knows, the language has many powerful features, but this power brings with it complexity, which in turn can make code more bug-prone and harder to read and maintain. The goal of this guide is to manage this complexity by describing in detail the dos and don'ts of writing C++ code. These rules exist to keep the code base manageable while still allowing coders to use C++ language features productively. Style, also known as readability, is what we call the conv
en
tions that govern our C++ code. The term Style is a bit of a misnomer, since these conv
en
tions cover far more than just source file formatting. One way in which we keep the code base manageable is by
en
forcing consist
en
cy. It is very important that any programmer be able to look at another's code and quickly understand it. Maintaining a uniform style and following conv
en
tions means that we can more easily use "pattern-matching" to infer what various symbols are and what invariants are true about them. Creating common, required idioms and patterns makes code much easier to understand. In some cases there might be good argum
en
ts for changing certain style rules, but we nonetheless keep things as they are in order to preserve consist
en
cy. Another issue this guide
address
es is that of C++ feature bloat. C++ is a huge language with many advanced features. In some cases we constrain, or ev
en
ban, use of certain features. We do this to keep code simple and to avoid the various common errors and problems that these features can cause. This guide
list
s these features and explains why their use is restricted. Op
en
-source projects developed by Google conform to the requirem
en
ts in this guide. Note that this guide is not a C++ tutorial: we assume that the reader is familiar with the language. Header Files In g
en
eral, every .cc file should have an associated .h file. There are some common exceptions, such as unittests and small .cc files containing just a main() function. Correct use of header files can make a huge differ
en
ce to the readability, size and performance of your code. The following rules will guide you through the various pitfalls of using header files. The #define Guard link ▶All header files should have #define guards to prev
en
t multiple inclusion. The format of the symbol name should be ___H_. To guarantee uniqu
en
ess, they should be based on the full path in a project's source tree. For example, the file foo/src/bar/baz.h in project foo should have the following guard: #ifndef FOO_BAR_BAZ_H_ #define FOO_BAR_BAZ_H_ ... #
en
dif // FOO_BAR_BAZ_H_ Header File Dep
en
d
en
cies link ▶Don't use an #include wh
en
a forward declaration would suffice. Wh
en
you include a header file you introduce a dep
en
d
en
cy that will cause your code to be recompiled wh
en
ever the header file changes. If your header file includes other header files, any change to those files will cause any code that includes your header to be recompiled. Therefore, we prefer to minimize includes, particularly includes of header files in other header files. You can significantly minimize the number of header files you need to include in your own header files by using forward declarations. For example, if your header file uses the File class in ways that do not require access to the declaration of the File class, your header file can just forward declare class File; instead of having to #include "file/base/file.h". How can we use a class Foo in a header file without access to its definition? We can declare data members of type Foo* or Foo&. We can declare (but not define) functions with argum
en
ts, and/or return values, of type Foo. (One exception is if an argum
en
t Foo or const Foo& has a non-explicit, one-argum
en
t constructor, in which case we need the full definition to support automatic type conversion.) We can declare static data members of type Foo. This is because static data members are defined outside the class definition. On the other hand, you must include the header file for Foo if your class subclasses Foo or has a data member of type Foo. Sometimes it makes s
en
se to have pointer (or better, scoped_ptr) members instead of object members. However, this complicates code readability and imposes a performance p
en
alty, so avoid doing this transformation if the only purpose is to minimize includes in header files. Of course, .cc files typically do require the definitions of the classes they use, and usually have to include several header files. Note: If you use a symbol Foo in your source file, you should bring in a definition for Foo yourself, either via an #include or via a forward declaration. Do not dep
en
d on the symbol being brought in transitively via headers not directly included. One exception is if Foo is used in myfile.cc, it's ok to #include (or forward-declare) Foo in myfile.h, instead of myfile.cc. Inline Functions link ▶Define functions inline only wh
en
they are small, say, 10 lines or less. Definition: You can declare functions in a way that allows the compiler to expand them inline rather than calling them through the usual function call mechanism. Pros: Inlining a function can g
en
erate more effici
en
t object code, as long as the inlined function is small. Feel free to inline accessors and mutators, and other short, performance-critical functions. Cons: Overuse of inlining can actually make programs slower. Dep
en
ding on a function's size, inlining it can cause the code size to increase or decrease. Inlining a very small accessor function will usually decrease code size while inlining a very large function can dramatically increase code size. On modern processors smaller code usually runs faster due to better use of the instruction cache. Decision: A dec
en
t rule of thumb is to not inline a function if it is more than 10 lines long. Beware of destructors, which are oft
en
longer than they appear because of implicit member- and base-destructor calls! Another useful rule of thumb: it's typically not cost effective to inline functions with loops or switch statem
en
ts (unless, in the common case, the loop or switch statem
en
t is never executed). It is important to know that functions are not always inlined ev
en
if they are declared as such; for example, virtual and recursive functions are not normally inlined. Usually recursive functions should not be inline. The main reason for making a virtual function inline is to place its definition in the class, either for conv
en
i
en
ce or to docum
en
t its behavior, e.g., for accessors and mutators. The -inl.h Files link ▶You may use file names with a -inl.h suffix to define complex inline functions wh
en
needed. The definition of an inline function needs to be in a header file, so that the compiler has the definition available for inlining at the call sites. However, implem
en
tation code properly belongs in .cc files, and we do not like to have much actual code in .h files unless there is a readability or performance advantage. If an inline function definition is short, with very little, if any, logic in it, you should put the code in your .h file. For example, accessors and mutators should certainly be inside a class definition. More complex inline functions may also be put in a .h file for the conv
en
i
en
ce of the implem
en
ter and callers, though if this makes the .h file too unwieldy you can instead put that code in a separate -inl.h file. This separates the implem
en
tation from the class definition, while still allowing the implem
en
tation to be included where necessary. Another use of -inl.h files is for definitions of function templates. This can be used to keep your template definitions easy to read. Do not forget that a -inl.h file requires a #define guard just like any other header file. Function Parameter Ordering link ▶Wh
en
defining a function, parameter order is: inputs, th
en
outputs. Parameters to C/C++ functions are either input to the function, output from the function, or both. Input parameters are usually values or const refer
en
ces, while output and input/output parameters will be non-const pointers. Wh
en
ordering function parameters, put all input-only parameters before any output parameters. In particular, do not add new parameters to the
en
d of the function just because they are new; place new input-only parameters before the output parameters. This is not a hard-and-fast rule. Parameters that are both input and output (oft
en
classes/structs) muddy the waters, and, as always, consist
en
cy with related functions may require you to b
en
d the rule. Names and Order of Includes link ▶Use standard order for readability and to avoid hidd
en
dep
en
d
en
cies: C library, C++ library, other libraries' .h, your project's .h. All of a project's header files should be
list
ed as desc
en
tants of the project's source directory without use of UNIX directory shortcuts . (the curr
en
t directory) or .. (the par
en
t directory). For example, google-awesome-project/src/base/logging.h should be included as #include "base/logging.h" In dir/foo.cc, whose main purpose is to implem
en
t or test the stuff in dir2/foo2.h, order your includes as follows: dir2/foo2.h (preferred location — see details below). C system files. C++ system files. Other libraries' .h files. Your project's .h files. The preferred ordering reduces hidd
en
dep
en
d
en
cies. We want every header file to be compilable on its own. The easiest way to achieve this is to make sure that every one of them is the first .h file #included in some .cc. dir/foo.cc and dir2/foo2.h are oft
en
in the same directory (e.g. base/basictypes_test.cc and base/basictypes.h), but can be in differ
en
t directories too. Within each section it is nice to order the includes alphabetically. For example, the includes in google-awesome-project/src/foo/internal/fooserver.cc might look like this: #include "foo/public/fooserver.h" // Preferred location. #include #include #include #include #include "base/basictypes.h" #include "base/commandlineflags.h" #include "foo/public/bar.h" Scoping Namespaces link ▶Unnamed namespaces in .cc files are
en
couraged. With named namespaces, choose the name based on the project, and possibly its path. Do not use a using-directive. Definition: Namespaces subdivide the global scope into distinct, named scopes, and so are useful for prev
en
ting name collisions in the global scope. Pros: Namespaces provide a (hierarchical) axis of naming, in addition to the (also hierarchical) name axis provided by classes. For example, if two differ
en
t projects have a class Foo in the global scope, these symbols may collide at compile time or at runtime. If each project places their code in a namespace, project1::Foo and project2::Foo are now distinct symbols that do not collide. Cons: Namespaces can be confusing, because they provide an additional (hierarchical) axis of naming, in addition to the (also hierarchical) name axis provided by classes. Use of unnamed spaces in header files can easily cause violations of the C++ One Definition Rule (ODR). Decision: Use namespaces according to the policy described below. Unnamed Namespaces Unnamed namespaces are allowed and ev
en
en
couraged in .cc files, to avoid runtime naming conflicts: namespace { // This is in a .cc file. // The cont
en
t of a namespace is not ind
en
ted
en
um { kUnused, kEOF, kError }; // Commonly used tok
en
s. bool AtEof() { return pos_ == kEOF; } // Uses our namespace's EOF. } // namespace However, file-scope declarations that are associated with a particular class may be declared in that class as types, static data members or static member functions rather than as members of an unnamed namespace. Terminate the unnamed namespace as shown, with a comm
en
t // namespace. Do not use unnamed namespaces in .h files. Named Namespaces Named namespaces should be used as follows: Namespaces wrap the
en
tire source file after includes, gflags definitions/declarations, and forward declarations of classes from other namespaces: // In the .h file namespace mynamespace { // All declarations are within the namespace scope. // Notice the lack of ind
en
tation. class MyClass { public: ... void Foo(); }; } // namespace mynamespace // In the .cc file namespace mynamespace { // Definition of functions is within scope of the namespace. void MyClass::Foo() { ... } } // namespace mynamespace The typical .cc file might have more complex detail, including the need to refer
en
ce classes in other namespaces. #include "a.h" DEFINE_bool(someflag, false, "dummy flag"); class C; // Forward declaration of class C in the global namespace. namespace a { class A; } // Forward declaration of a::A. namespace b { ...code for b... // Code goes against the left margin. } // namespace b Do not declare anything in namespace std, not ev
en
forward declarations of standard library classes. Declaring
en
tities in namespace std is undefined behavior, i.e., not portable. To declare
en
tities from the standard library, include the appropriate header file. You may not use a using-directive to make all names from a namespace available. // Forbidd
en
-- This pollutes the namespace. using namespace foo; You may use a using-declaration anywhere in a .cc file, and in functions, methods or classes in .h files. // OK in .cc files. // Must be in a function, method or class in .h files. using ::foo::bar; Namespace aliases are allowed anywhere in a .cc file, anywhere inside the named namespace that wraps an
en
tire .h file, and in functions and methods. // Short
en
access to some commonly used names in .cc files. namespace fbz = ::foo::bar::baz; // Short
en
access to some commonly used names (in a .h file). namespace librarian { // The following alias is available to all files including // this header (in namespace librarian): // alias names should therefore be chos
en
consist
en
tly // within a project. namespace pd_s = ::pipeline_diagnostics::sidetable; inline void my_inline_function() { // namespace alias local to a function (or method). namespace fbz = ::foo::bar::baz; ... } } // namespace librarian Note that an alias in a .h file is visible to everyone #including that file, so public headers (those available outside a project) and headers transitively #included by them, should avoid defining aliases, as part of the g
en
eral goal of keeping public APIs as small as possible. Nested Classes link ▶Although you may use public nested classes wh
en
they are part of an interface, consider a namespace to keep declarations out of the global scope. Definition: A class can define another class within it; this is also called a member class. class Foo { private: // Bar is a member class, nested within Foo. class Bar { ... }; }; Pros: This is useful wh
en
the nested (or member) class is only used by the
en
closing class; making it a member puts it in the
en
closing class scope rather than polluting the outer scope with the class name. Nested classes can be forward declared within the
en
closing class and th
en
defined in the .cc file to avoid including the nested class definition in the
en
closing class declaration, since the nested class definition is usually only relevant to the implem
en
tation. Cons: Nested classes can be forward-declared only within the definition of the
en
closing class. Thus, any header file manipulating a Foo::Bar* pointer will have to include the full class declaration for Foo. Decision: Do not make nested classes public unless they are actually part of the interface, e.g., a class that holds a set of options for some method. Nonmember, Static Member, and Global Functions link ▶Prefer nonmember functions within a namespace or static member functions to global functions; use completely global functions rarely. Pros: Nonmember and static member functions can be useful in some situations. Putting nonmember functions in a namespace avoids polluting the global namespace. Cons: Nonmember and static member functions may make more s
en
se as members of a new class, especially if they access external resources or have significant dep
en
d
en
cies. Decision: Sometimes it is useful, or ev
en
necessary, to define a function not
bound
to a class instance. Such a function can be either a static member or a nonmember function. Nonmember functions should not dep
en
d on external variables, and should nearly always exist in a namespace. Rather than creating classes only to group static member functions which do not share static data, use namespaces instead. Functions defined in the same compilation unit as production classes may introduce unnecessary coupling and link-time dep
en
d
en
cies wh
en
directly called from other compilation units; static member functions are particularly susceptible to this. Consider extracting a new class, or placing the functions in a namespace possibly in a separate library. If you must define a nonmember function and it is only needed in its .cc file, use an unnamed namespace or static linkage (eg static int Foo() {...}) to limit its scope. Local Variables link ▶Place a function's variables in the narrowest scope possible, and initialize variables in the declaration. C++ allows you to declare variables anywhere in a function. We
en
courage you to declare them in as local a scope as possible, and as close to the first use as possible. This makes it easier for the reader to find the declaration and see what type the variable is and what it was initialized to. In particular, initialization should be used instead of declaration and assignm
en
t, e.g. int i; i = f(); // Bad -- initialization separate from declaration. int j = g(); // Good -- declaration has initialization. Note that gcc implem
en
ts for (int i = 0; i < 10; ++i) correctly (the scope of i is only the scope of the for loop), so you can th
en
reuse i in another for loop in the same scope. It also correctly scopes declarations in if and while statem
en
ts, e.g. while (const char* p = strchr(str, '/')) str = p + 1; There is one caveat: if the variable is an object, its constructor is
invoke
d every time it
en
ters scope and is created, and its destructor is
invoke
d every time it goes out of scope. // Ineffici
en
t implem
en
tation: for (int i = 0; i < 1000000; ++i) { Foo f; // My ctor and dtor get called 1000000 times each. f.DoSomething(i); } It may be more effici
en
t to declare such a variable used in a loop outside that loop: Foo f; // My ctor and dtor get called once each. for (int i = 0; i < 1000000; ++i) { f.DoSomething(i); } Static and Global Variables link ▶Static or global variables of class type are forbidd
en
: they cause hard-to-find bugs due to indeterminate order of construction and destruction. Objects with static storage duration, including global variables, static variables, static class member variables, and function static variables, must be Plain Old Data (POD): only ints, chars, floats, or pointers, or arrays/structs of POD. The order in which class constructors and initializers for static variables are called is only partially specified in C++ and can ev
en
change from build to build, which can cause bugs that are difficult to find. Therefore in addition to banning globals of class type, we do not allow static POD variables to be initialized with the result of a function, unless that function (such as get
en
v(), or getpid()) does not itself dep
en
d on any other globals. Likewise, the order in which destructors are called is defined to be the reverse of the order in which the constructors were called. Since constructor order is indeterminate, so is destructor order. For example, at program-
en
d time a static variable might have be
en
destroyed, but code still running -- perhaps in another thread -- tries to access it and fails. Or the destructor for a static 'string' variable might be run prior to the destructor for another variable that contains a refer
en
ce to that string. As a result we only allow static variables to contain POD data. This rule completely disallows vector (use C arrays instead), or string (use const char []). If you need a static or global variable of a class type, consider initializing a pointer (which will never be freed), from either your main() function or from pthread_once(). Note that this must be a raw pointer, not a "smart" pointer, since the smart pointer's destructor will have the order-of-destructor issue that we are trying to avoid. Classes Classes are the fundam
en
tal unit of code in C++. Naturally, we use them ext
en
sively. This section
list
s the main dos and don'ts you should follow wh
en
writing a class. Doing Work in Constructors link ▶In g
en
eral, constructors should merely set member variables to their initial values. Any complex initialization should go in an explicit Init() method. Definition: It is possible to perform initialization in the body of the constructor. Pros: Conv
en
i
en
ce in typing. No need to worry about whether the class has be
en
initialized or not. Cons: The problems with doing work in constructors are: There is no easy way for constructors to signal errors, short of using exceptions (which are forbidd
en
). If the work fails, we now have an object whose initialization code failed, so it may be an indeterminate state. If the work calls virtual functions, these calls will not get dispatched to the subclass implem
en
tations. Future modification to your class can quietly introduce this problem ev
en
if your class is not curr
en
tly subclassed, causing much confusion. If someone creates a global variable of this type (which is against the rules, but still), the constructor code will be called before main(), possibly breaking some implicit assumptions in the constructor code. For instance, gflags will not yet have be
en
initialized. Decision: If your object requires non-trivial initialization, consider having an explicit Init() method. In particular, constructors should not call virtual functions, attempt to raise errors, access pot
en
tially uninitialized global variables, etc. Default Constructors link ▶You must define a default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly. Definition: The default constructor is called wh
en
we new a class object with no argum
en
ts. It is always called wh
en
calling new[] (for arrays). Pros: Initializing structures by default, to hold "impossible" values, makes debugging much easier. Cons: Extra work for you, the code writer. Decision: If your class defines member variables and has no other constructors you must define a default constructor (one that takes no argum
en
ts). It should preferably initialize the object in such a way that its internal state is consist
en
t and valid. The reason for this is that if you have no other constructors and do not define a default constructor, the compiler will g
en
erate one for you. This compiler g
en
erated constructor may not initialize your object s
en
sibly. If your class inherits from an existing class but you add no new member variables, you are not required to have a default constructor. Explicit Constructors link ▶Use the C++ keyword explicit for constructors with one argum
en
t. Definition: Normally, if a constructor takes one argum
en
t, it can be used as a conversion. For instance, if you define Foo::Foo(string name) and th
en
pass a string to a function that expects a Foo, the constructor will be called to convert the string into a Foo and will pass the Foo to your function for you. This can be conv
en
i
en
t but is also a source of trouble wh
en
things get converted and new objects created without you meaning them to. Declaring a constructor explicit prev
en
ts it from being
invoke
d implicitly as a conversion. Pros: Avoids undesirable conversions. Cons: None. Decision: We require all single argum
en
t constructors to be explicit. Always put explicit in front of one-argum
en
t constructors in the class definition: explicit Foo(string name); The exception is copy constructors, which, in the rare cases wh
en
we allow them, should probably not be explicit. Classes that are int
en
ded to be transpar
en
t wrappers around other classes are also exceptions. Such exceptions should be clearly marked with comm
en
ts. Copy Constructors link ▶Provide a copy constructor and assignm
en
t operator only wh
en
necessary. Otherwise, disable them with DISALLOW_COPY_AND_ASSIGN. Definition: The copy constructor and assignm
en
t operator are used to create copies of objects. The copy constructor is implicitly
invoke
d by the compiler in some situations, e.g. passing objects by value. Pros: Copy constructors make it easy to copy objects. STL containers require that all cont
en
ts be copyable and assignable. Copy constructors can be more effici
en
t than CopyFrom()-style workarounds because they combine construction with copying, the compiler can elide them in some contexts, and they make it easier to avoid heap allocation. Cons: Implicit copying of objects in C++ is a rich source of bugs and of performance problems. It also reduces readability, as it becomes hard to track which objects are being passed around by value as opposed to by refer
en
ce, and therefore where changes to an object are reflected. Decision: Few classes need to be copyable. Most should have neither a copy constructor nor an assignm
en
t operator. In many situations, a pointer or refer
en
ce will work just as well as a copied value, with better performance. For example, you can pass function parameters by refer
en
ce or pointer instead of by value, and you can store pointers rather than objects in an STL container. If your class needs to be copyable, prefer providing a copy method, such as CopyFrom() or Clone(), rather than a copy constructor, because such methods cannot be
invoke
d implicitly. If a copy method is insuffici
en
t in your situation (e.g. for performance reasons, or because your class needs to be stored by value in an STL container), provide both a copy constructor and assignm
en
t operator. If your class does not need a copy constructor or assignm
en
t operator, you must explicitly disable them. To do so, add dummy declarations for the copy constructor and assignm
en
t operator in the private: section of your class, but do not provide any corresponding definition (so that any attempt to use them results in a link error). For conv
en
i
en
ce, a DISALLOW_COPY_AND_ASSIGN macro can be used: // A macro to disallow the copy constructor and operator= functions // This should be used in the private: declarations for a class #define DISALLOW_COPY_AND_ASSIGN(Typ
eN
ame) \ Typ
eN
ame(const Typ
eN
ame&); \ void operator=(const Typ
eN
ame&) Th
en
, in class Foo: class Foo { public: Foo(int f); ~Foo(); private: DISALLOW_COPY_AND_ASSIGN(Foo); }; Structs vs. Classes link ▶Use a struct only for passive objects that carry data; everything else is a class. The struct and class keywords behave almost id
en
tically in C++. We add our own semantic meanings to each keyword, so you should use the appropriate keyword for the data-type you're defining. structs should be used for passive objects that carry data, and may have associated constants, but lack any functionality other than access/setting the data members. The accessing/setting of fields is done by directly accessing the fields rather than through method invocations. Methods should not provide behavior but should only be used to set up the data members, e.g., constructor, destructor, Initialize(), Reset(), Validate(). If more functionality is required, a class is more appropriate. If in doubt, make it a class. For consist
en
cy with STL, you can use struct instead of class for functors and traits. Note that member variables in structs and classes have differ
en
t naming rules. Inheritance link ▶Composition is oft
en
more appropriate than inheritance. Wh
en
using inheritance, make it public. Definition: Wh
en
a sub-class inherits from a base class, it includes the definitions of all the data and operations that the par
en
t base class defines. In practice, inheritance is used in two major ways in C++: implem
en
tation inheritance, in which actual code is inherited by the child, and interface inheritance, in which only method names are inherited. Pros: Implem
en
tation inheritance reduces code size by re-using the base class code as it specializes an existing type. Because inheritance is a compile-time declaration, you and the compiler can understand the operation and detect errors. Interface inheritance can be used to programmatically
en
force that a class expose a particular API. Again, the compiler can detect errors, in this case, wh
en
a class does not define a necessary method of the API. Cons: For implem
en
tation inheritance, because the code implem
en
ting a sub-class is spread betwe
en
the base and the sub-class, it can be more difficult to understand an implem
en
tation. The sub-class cannot override functions that are not virtual, so the sub-class cannot change implem
en
tation. The base class may also define some data members, so that specifies physical layout of the base class. Decision: All inheritance should be public. If you want to do private inheritance, you should be including an instance of the base class as a member instead. Do not overuse implem
en
tation inheritance. Composition is oft
en
more appropriate. Try to restrict use of inheritance to the "is-a" case: Bar subclasses Foo if it can reasonably be said that Bar "is a kind of" Foo. Make your destructor virtual if necessary. If your class has virtual methods, its destructor should be virtual. Limit the use of protected to those member functions that might need to be accessed from subclasses. Note that data members should be private. Wh
en
redefining an inherited virtual function, explicitly declare it virtual in the declaration of the derived class. Rationale: If virtual is omitted, the reader has to check all ancestors of the class in question to determine if the function is virtual or not. Multiple Inheritance link ▶Only very rarely is multiple implem
en
tation inheritance actually useful. We allow multiple inheritance only wh
en
at most one of the base classes has an implem
en
tation; all other base classes must be pure interface classes tagged with the Interface suffix. Definition: Multiple inheritance allows a sub-class to have more than one base class. We distinguish betwe
en
base classes that are pure interfaces and those that have an implem
en
tation. Pros: Multiple implem
en
tation inheritance may let you re-use ev
en
more code than single inheritance (see Inheritance). Cons: Only very rarely is multiple implem
en
tation inheritance actually useful. Wh
en
multiple implem
en
tation inheritance seems like the solution, you can usually find a differ
en
t, more explicit, and cleaner solution. Decision: Multiple inheritance is allowed only wh
en
all superclasses, with the possible exception of the first one, are pure interfaces. In order to
en
sure that they remain pure interfaces, they must
en
d with the Interface suffix. Note: There is an exception to this rule on Windows. Interfaces link ▶Classes that satisfy certain conditions are allowed, but not required, to
en
d with an Interface suffix. Definition: A class is a pure interface if it meets the following requirem
en
ts: It has only public pure virtual ("= 0") methods and static methods (but see below for destructor). It may not have non-static data members. It need not have any constructors defined. If a constructor is provided, it must take no argum
en
ts and it must be protected. If it is a subclass, it may only be derived from classes that satisfy these conditions and are tagged with the Interface suffix. An interface class can never be directly instantiated because of the pure virtual method(s) it declares. To make sure all implem
en
tations of the interface can be destroyed correctly, they must also declare a virtual destructor (in an exception to the first rule, this should not be pure). See Stroustrup, The C++ Programming Language, 3rd edition, section 12.4 for details. Pros: Tagging a class with the Interface suffix lets others know that they must not add implem
en
ted methods or non static data members. This is particularly important in the case of multiple inheritance. Additionally, the interface concept is already well-understood by Java programmers. Cons: The Interface suffix l
en
gth
en
s the class name, which can make it harder to read and understand. Also, the interface property may be considered an implem
en
tation detail that shouldn't be exposed to cli
en
ts. Decision: A class may
en
d with Interface only if it meets the above requirem
en
ts. We do not require the converse, however: classes that meet the above requirem
en
ts are not required to
en
d with Interface. Operator Overloading link ▶Do not overload operators except in rare, special circumstances. Definition: A class can define that operators such as + and / operate on the class as if it were a built-in type. Pros: Can make code appear more intuitive because a class will behave in the same way as built-in types (such as int). Overloaded operators are more playful names for functions that are less-colorfully named, such as Equals() or Add(). For some template functions to work correctly, you may need to define operators. Cons: While operator overloading can make code more intuitive, it has several drawbacks: It can fool our intuition into thinking that exp
en
sive operations are cheap, built-in operations. It is much harder to find the call sites for overloaded operators. Searching for Equals() is much easier than searching for relevant invocations of ==. Some operators work on pointers too, making it easy to introduce bugs. Foo + 4 may do one thing, while &Foo + 4 does something totally differ
en
t. The compiler does not complain for either of these, making this very hard to debug. Overloading also has surprising ramifications. For instance, if a class overloads unary operator&, it cannot safely be forward-declared. Decision: In g
en
eral, do not overload operators. The assignm
en
t operator (operator=), in particular, is insidious and should be avoided. You can define functions like Equals() and CopyFrom() if you need them. Likewise, avoid the dangerous unary operator& at all costs, if there's any possibility the class might be forward-declared. However, there may be rare cases where you need to overload an operator to interoperate with templates or "standard" C++ classes (such as operator<<(ostream&, const T&) for logging). These are
accept
able if fully justified, but you should try to avoid these wh
en
ever possible. In particular, do not overload operator== or operator< just so that your class can be used as a key in an STL container; instead, you should create equality and comparison functor types wh
en
declaring the container. Some of the STL algorithms do require you to overload operator==, and you may do so in these cases, provided you docum
en
t why. See also Copy Constructors and Function Overloading. Access Control link ▶Make data members private, and provide access to them through accessor functions as needed (for technical reasons, we allow data members of a test fixture class to be protected wh
en
using Google Test). Typically a variable would be called foo_ and the accessor function foo(). You may also want a mutator function set_foo(). Exception: static const data members (typically called kFoo) need not be private. The definitions of accessors are usually inlined in the header file. See also Inheritance and Function Names. Declaration Order link ▶Use the specified order of declarations within a class: public: before private:, methods before data members (variables), etc. Your class definition should start with its public: section, followed by its protected: section and th
en
its private: section. If any of these sections are empty, omit them. Within each section, the declarations g
en
erally should be in the following order: Typedefs and
En
ums Constants (static const data members) Constructors Destructor Methods, including static methods Data Members (except static const data members) Fri
en
d declarations should always be in the private section, and the DISALLOW_COPY_AND_ASSIGN macro invocation should be at the
en
d of the private: section. It should be the last thing in the class. See Copy Constructors. Method definitions in the corresponding .cc file should be the same as the declaration order, as much as possible. Do not put large method definitions inline in the class definition. Usually, only trivial or performance-critical, and very short, methods may be defined inline. See Inline Functions for more details. Write Short Functions link ▶Prefer small and focused functions. We recognize that long functions are sometimes appropriate, so no hard limit is placed on functions l
en
gth. If a function exceeds about 40 lines, think about whether it can be brok
en
up without harming the structure of the program. Ev
en
if your long function works perfectly now, someone modifying it in a few months may add new behavior. This could result in bugs that are hard to find. Keeping your functions short and simple makes it easier for other people to read and modify your code. You could find long and complicated functions wh
en
working with some code. Do not be intimidated by modifying existing code: if working with such a function proves to be difficult, you find that errors are hard to debug, or you want to use a piece of it in several differ
en
t contexts, consider breaking up the function into smaller and more manageable pieces. Google-Specific Magic There are various tricks and utilities that we use to make C++ code more robust, and various ways we use C++ that may differ from what you see elsewhere. Smart Pointers link ▶If you actually need pointer semantics, scoped_ptr is great. You should only use std::tr1::shared_ptr under very specific conditions, such as wh
en
objects need to be held by STL containers. You should never use auto_ptr. "Smart" pointers are objects that act like pointers but have added semantics. Wh
en
a scoped_ptr is destroyed, for instance, it deletes the object it's pointing to. shared_ptr is the same way, but implem
en
ts refer
en
ce-counting so only the last pointer to an object deletes it. G
en
erally speaking, we prefer that we design code with clear object ownership. The clearest object ownership is obtained by using an object directly as a field or local variable, without using pointers at all. On the other extreme, by their very definition, refer
en
ce counted pointers are owned by nobody. The problem with this design is that it is easy to create circular refer
en
ces or other strange conditions that cause an object to never be deleted. It is also slow to perform atomic operations every time a value is copied or assigned. Although they are not recomm
en
ded, refer
en
ce counted pointers are sometimes the simplest and most elegant way to solve a problem. cpplint link ▶Use cpplint.py to detect style errors. cpplint.py is a tool that reads a source file and id
en
tifies many style errors. It is not perfect, and has both false positives and false negatives, but it is still a valuable tool. False positives can be ignored by putting // NOLINT at the
en
d of the line. Some projects have instructions on how to run cpplint.py from their project tools. If the project you are contributing to does not, you can download cpplint.py separately. Other C++ Features Refer
en
ce Argum
en
ts link ▶All parameters passed by refer
en
ce must be labeled const. Definition: In C, if a function needs to modify a variable, the parameter must use a pointer, eg int foo(int *pval). In C++, the function can alternatively declare a refer
en
ce parameter: int foo(int &val). Pros: Defining a parameter as refer
en
ce avoids ugly code like (*pval)++. Necessary for some applications like copy constructors. Makes it clear, unlike with pointers, that NULL is not a possible value. Cons: Refer
en
ces can be confusing, as they have value syntax but pointer semantics. Decision: Within function parameter
list
s all refer
en
ces must be const: void Foo(const string &in, string *out); In fact it is a very strong conv
en
tion in Google code that input argum
en
ts are values or const refer
en
ces while output argum
en
ts are pointers. Input parameters may be const pointers, but we never allow non-const refer
en
ce parameters. One case wh
en
you might want an input parameter to be a const pointer is if you want to emphasize that the argum
en
t is not copied, so it must exist for the lifetime of the object; it is usually best to docum
en
t this in comm
en
ts as well. STL adapters such as bind2nd and mem_fun do not permit refer
en
ce parameters, so you must declare functions with pointer parameters in these cases, too. Function Overloading link ▶Use overloaded functions (including constructors) only if a reader looking at a call site can get a good idea of what is happ
en
ing without having to first figure out exactly which overload is being called. Definition: You may write a function that takes a const string& and overload it with another that takes const char*. class MyClass { public: void Analyze(const string &text); void Analyze(const char *text, size_t textl
en
); }; Pros: Overloading can make code more intuitive by allowing an id
en
tically-named function to take differ
en
t argum
en
ts. It may be necessary for templatized code, and it can be conv
en
i
en
t for Visitors. Cons: If a function is overloaded by the argum
en
t types alone, a reader may have to understand C++'s complex matching rules in order to tell what's going on. Also many people are confused by the semantics of inheritance if a derived class overrides only some of the variants of a function. Decision: If you want to overload a function, consider qualifying the name with some information about the argum
en
ts, e.g., App
en
dString(), App
en
dInt() rather than just App
en
d(). Default Argum
en
ts link ▶We do not allow default function parameters, except in a few uncommon situations explained below. Pros: Oft
en
you have a function that uses lots of default values, but occasionally you want to override the defaults. Default parameters allow an easy way to do this without having to define many functions for the rare exceptions. Cons: People oft
en
figure out how to use an API by looking at existing code that uses it. Default parameters are more difficult to maintain because copy-and-paste from previous code may not reveal all the parameters. Copy-and-pasting of code segm
en
ts can cause major problems wh
en
the default argum
en
ts are not appropriate for the new code. Decision: Except as described below, we require all argum
en
ts to be explicitly specified, to force programmers to consider the API and the values they are passing for each argum
en
t rather than sil
en
tly
accept
ing defaults they may not be aware of. One specific exception is wh
en
default argum
en
ts are used to simulate variable-l
en
gth argum
en
t
list
s. // Support up to 4 params by using a default empty AlphaNum. string StrCat(const AlphaNum &a, const AlphaNum &b = gEmptyAlphaNum, const AlphaNum &c = gEmptyAlphaNum, const AlphaNum &d = gEmptyAlphaNum); Variable-L
en
gth Arrays and alloca() link ▶We do not allow variable-l
en
gth arrays or alloca(). Pros: Variable-l
en
gth arrays have natural-looking syntax. Both variable-l
en
gth arrays and alloca() are very effici
en
t. Cons: Variable-l
en
gth arrays and alloca are not part of Standard C++. More importantly, they allocate a data-dep
en
d
en
t amount of stack space that can trigger difficult-to-find memory overwriting bugs: "It ran fine on my machine, but dies mysteriously in production". Decision: Use a safe allocator instead, such as scoped_ptr/scoped_array. Fri
en
ds link ▶We allow use of fri
en
d classes and functions, within reason. Fri
en
ds should usually be defined in the same file so that the reader does not have to look in another file to find uses of the private members of a class. A common use of fri
en
d is to have a FooBuilder class be a fri
en
d of Foo so that it can construct the inner state of Foo correctly, without exposing this state to the world. In some cases it may be useful to make a unittest class a fri
en
d of the class it tests. Fri
en
ds ext
en
d, but do not break, the
en
capsulation
bound
ary of a class. In some cases this is better than making a member public wh
en
you want to give only one other class access to it. However, most classes should interact with other classes solely through their public members. Exceptions link ▶We do not use C++ exceptions. Pros: Exceptions allow higher levels of an application to decide how to handle "can't happ
en
" failures in deeply nested functions, without the obscuring and error-prone bookkeeping of error codes. Exceptions are used by most other modern languages. Using them in C++ would make it more consist
en
t with Python, Java, and the C++ that others are familiar with. Some third-party C++ libraries use exceptions, and turning them off internally makes it harder to integrate with those libraries. Exceptions are the only way for a constructor to fail. We can simulate this with a factory function or an Init() method, but these require heap allocation or a new "
invalid
" state, respectively. Exceptions are really handy in testing frameworks. Cons: Wh
en
you add a throw statem
en
t to an existing function, you must examine all of its transitive callers. Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly. More g
en
erally, exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. This causes maintainability and debugging difficulties. You can minimize this cost via some rules on how and where exceptions can be used, but at the cost of more that a developer needs to know and understand. Exception safety requires both RAII and differ
en
t coding practices. Lots of supporting machinery is needed to make writing correct exception-safe code easy. Further, to avoid requiring readers to understand the
en
tire call graph, exception-safe code must isolate logic that writes to persist
en
t state into a "commit" phase. This will have both b
en
efits and costs (perhaps where you're forced to obfuscate code to isolate the commit). Allowing exceptions would force us to always pay those costs ev
en
wh
en
they're not worth it. Turning on exceptions adds data to each binary produced, increasing compile time (probably slightly) and possibly increasing
address
space pressure. The availability of exceptions may
en
courage developers to throw them wh
en
they are not appropriate or recover from them wh
en
it's not safe to do so. For example,
invalid
user input should not cause exceptions to be thrown. We would need to make the style guide ev
en
longer to docum
en
t these restrictions! Decision: On their face, the b
en
efits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dep
en
d
en
t code. If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that g
en
erates exceptions. Giv
en
that Google's existing code is not exception-tolerant, the costs of using exceptions are somewhat greater than the costs in a new project. The conversion process would be slow and error-prone. We don't believe that the available alternatives to exceptions, such as error codes and assertions, introduce a significant burd
en
. Our advice against using exceptions is not predicated on philosophical or moral grounds, but practical ones. Because we'd like to use our op
en
-source projects at Google and it's difficult to do so if those projects use exceptions, we need to advise against exceptions in Google op
en
-source projects as well. Things would probably be differ
en
t if we had to do it all over again from scratch. There is an exception to this rule (no pun int
en
ded) for Windows code. Run-Time Type Information (RTTI) link ▶We do not use Run Time Type Information (RTTI). Definition: RTTI allows a programmer to query the C++ class of an object at run time. Pros: It is useful in some unittests. For example, it is useful in tests of factory classes where the test has to verify that a newly created object has the expected dynamic type. In rare circumstances, it is useful ev
en
outside of tests. Cons: A query of type during run-time typically means a design problem. If you need to know the type of an object at runtime, that is oft
en
an indication that you should reconsider the design of your class. Decision: Do not use RTTI, except in unittests. If you find yourself in need of writing code that behaves differ
en
tly based on the class of an object, consider one of the alternatives to querying the type. Virtual methods are the preferred way of executing differ
en
t code paths dep
en
ding on a specific subclass type. This puts the work within the object itself. If the work belongs outside the object and instead in some processing code, consider a double-dispatch solution, such as the Visitor design pattern. This allows a facility outside the object itself to determine the type of class using the built-in type system. If you think you truly cannot use those ideas, you may use RTTI. But think twice about it. :-) Th
en
think twice again. Do not hand-implem
en
t an RTTI-like workaround. The argum
en
ts against RTTI apply just as much to workarounds like class hierarchies with type tags. Casting link ▶Use C++ casts like static_cast(). Do not use other cast formats like int y = (int)x; or int y = int(x);. Definition: C++ introduced a differ
en
t cast system from C that distinguishes the types of cast operations. Pros: The problem with C casts is the ambiguity of the operation; sometimes you are doing a conversion (e.g., (int)3.5) and sometimes you are doing a cast (e.g., (int)"hello"); C++ casts avoid this. Additionally C++ casts are more visible wh
en
searching for them. Cons: The syntax is nasty. Decision: Do not use C-style casts. Instead, use these C++-style casts. Use static_cast as the equival
en
t of a C-style cast that does value conversion, or wh
en
you need to explicitly up-cast a pointer from a class to its superclass. Use const_cast to remove the const qualifier (see const). Use reinterpret_cast to do unsafe conversions of pointer types to and from integer and other pointer types. Use this only if you know what you are doing and you understand the aliasing issues. Do not use dynamic_cast except in test code. If you need to know type information at runtime in this way outside of a unittest, you probably have a design flaw. Streams link ▶Use streams only for logging. Definition: Streams are a replacem
en
t for printf() and scanf(). Pros: With streams, you do not need to know the type of the object you are printing. You do not have problems with format strings not matching the argum
en
t
list
. (Though with gcc, you do not have that problem with printf either.) Streams have automatic constructors and destructors that op
en
and close the relevant files. Cons: Streams make it difficult to do functionality like pread(). Some formatting (particularly the common format string idiom %.*s) is difficult if not impossible to do effici
en
tly using streams without using printf-like hacks. Streams do not support operator reordering (the %1s directive), which is helpful for internationalization. Decision: Do not use streams, except where required by a logging interface. Use printf-like routines instead. There are various pros and cons to using streams, but in this case, as in many other cases, consist
en
cy trumps the debate. Do not use streams in your code. Ext
en
ded Discussion There has be
en
debate on this issue, so this explains the reasoning in greater depth. Recall the Only One Way guiding principle: we want to make sure that wh
en
ever we do a certain type of I/O, the code looks the same in all those places. Because of this, we do not want to allow users to decide betwe
en
using streams or using printf plus Read/Write/etc. Instead, we should settle on one or the other. We made an exception for logging because it is a pretty specialized application, and for historical reasons. Propon
en
ts of streams have argued that streams are the obvious choice of the two, but the issue is not actually so clear. For every advantage of streams they point out, there is an equival
en
t disadvantage. The biggest advantage is that you do not need to know the type of the object to be printing. This is a fair point. But, there is a downside: you can easily use the wrong type, and the compiler will not warn you. It is easy to make this kind of mistake without knowing wh
en
using streams. cout << this; // Prints the
address
cout << *this; // Prints the cont
en
ts The compiler does not g
en
erate an error because << has be
en
overloaded. We discourage overloading for just this reason. Some say printf formatting is ugly and hard to read, but streams are oft
en
no better. Consider the following two fragm
en
ts, both with the same typo. Which is easier to discover? cerr << "Error connecting to '"
hostname.first << ":"
hostname.second << ": "
hostname.first, foo->bar()->hostname.second, strerror(errno)); And so on and so forth for any issue you might bring up. (You could argue, "Things would be better with the right wrappers," but if it is true for one scheme, is it not also true for the other? Also, remember the goal is to make the language smaller, not add yet more machinery that someone has to learn.) Either path would yield differ
en
t advantages and disadvantages, and there is not a clearly superior solution. The simplicity doctrine mandates we settle on one of them though, and the majority decision was on printf + read/write. Preincrem
en
t and Predecrem
en
t link ▶Use prefix form (++i) of the increm
en
t and decrem
en
t operators with iterators and other template objects. Definition: Wh
en
a variable is increm
en
ted (++i or i++) or decrem
en
ted (--i or i--) and the value of the expression is not used, one must decide whether to preincrem
en
t (decrem
en
t) or postincrem
en
t (decrem
en
t). Pros: Wh
en
the return value is ignored, the "pre" form (++i) is never less effici
en
t than the "post" form (i++), and is oft
en
more effici
en
t. This is because post-increm
en
t (or decrem
en
t) requires a copy of i to be made, which is the value of the expression. If i is an iterator or other non-scalar type, copying i could be exp
en
sive. Since the two types of increm
en
t behave the same wh
en
the value is ignored, why not just always pre-increm
en
t? Cons: The tradition developed, in C, of using post-increm
en
t wh
en
the expression value is not used, especially in for loops. Some find post-increm
en
t easier to read, since the "subject" (i) precedes the "verb" (++), just like in
En
glish. Decision: For simple scalar (non-object) values there is no reason to prefer one form and we allow either. For iterators and other template types, use pre-increm
en
t. Use of const link ▶We strongly recomm
en
d that you use const wh
en
ever it makes s
en
se to do so. Definition: Declared variables and parameters can be preceded by the keyword const to indicate the variables are not changed (e.g., const int foo). Class functions can have the const qualifier to indicate the function does not change the state of the class member variables (e.g., class Foo { int Bar(char c) const; };). Pros: Easier for people to understand how variables are being used. Allows the compiler to do better type checking, and, conceivably, g
en
erate better code. Helps people convince themselves of program correctness because they know the functions they call are limited in how they can modify your variables. Helps people know what functions are safe to use without locks in multi-threaded programs. Cons: const is viral: if you pass a const variable to a function, that function must have const in its prototype (or the variable will need a const_cast). This can be a particular problem wh
en
calling library functions. Decision: const variables, data members, methods and argum
en
ts add a level of compile-time type checking; it is better to detect errors as soon as possible. Therefore we strongly recomm
en
d that you use const wh
en
ever it makes s
en
se to do so: If a function does not modify an argum
en
t passed by refer
en
ce or by pointer, that argum
en
t should be const. Declare methods to be const wh
en
ever possible. Accessors should almost always be const. Other methods should be const if they do not modify any data members, do not call any non-const methods, and do not return a non-const pointer or non-const refer
en
ce to a data member. Consider making data members const wh
en
ever they do not need to be modified after construction. However, do not go crazy with const. Something like const int * const * const x; is likely overkill, ev
en
if it accurately describes how const x is. Focus on what's really useful to know: in this case, const int** x is probably suffici
en
t. The mutable keyword is allowed but is unsafe wh
en
used with threads, so thread safety should be carefully considered first. Where to put the const Some people favor the form int const *foo to const int* foo. They argue that this is more readable because it's more consist
en
t: it keeps the rule that const always follows the object it's describing. However, this consist
en
cy argum
en
t doesn't apply in this case, because the "don't go crazy" dictum eliminates most of the uses you'd have to be consist
en
t with. Putting the const first is arguably more readable, since it follows
En
glish in putting the "adjective" (const) before the "noun" (int). That said, while we
en
courage putting const first, we do not require it. But be consist
en
t with the code around you! Integer Types link ▶Of the built-in C++ integer types, the only one used is int. If a program needs a variable of a differ
en
t size, use a precise-width integer type from , such as int16_t. Definition: C++ does not specify the sizes of its integer types. Typically people assume that short is 16 bits, int is 32 bits, long is 32 bits and long long is 64 bits. Pros: Uniformity of declaration. Cons: The sizes of integral types in C++ can vary based on compiler and architecture. Decision: defines types like int16_t, uint32_t, int64_t, etc. You should always use those in prefer
en
ce to short, unsigned long long and the like, wh
en
you need a guarantee on the size of an integer. Of the C integer types, only int should be used. Wh
en
appropriate, you are welcome to use standard types like size_t and ptrdiff_t. We use int very oft
en
, for integers we know are not going to be too big, e.g., loop counters. Use plain old int for such things. You should assume that an int is at least 32 bits, but don't assume that it has more than 32 bits. If you need a 64-bit integer type, use int64_t or uint64_t. For integers we know can be "big", use int64_t. You should not use the unsigned integer types such as uint32_t, unless the quantity you are repres
en
ting is really a bit pattern rather than a number, or unless you need defined twos-complem
en
t overflow. In particular, do not use unsigned types to say a number will never be negative. Instead, use assertions for this. On Unsigned Integers Some people, including some textbook authors, recomm
en
d using unsigned types to repres
en
t numbers that are never negative. This is int
en
ded as a form of self-docum
en
tation. However, in C, the advantages of such docum
en
tation are outweighed by the real bugs it can introduce. Consider: for (unsigned int i = foo.L
en
gth()-1; i >= 0; --i) ... This code will never terminate! Sometimes gcc will notice this bug and warn you, but oft
en
it will not. Equally bad bugs can occur wh
en
comparing signed and unsigned variables. Basically, C's type-promotion scheme causes unsigned types to behave differ
en
tly than one might expect. So, docum
en
t that a variable is non-negative using assertions. Don't use an unsigned type. 64-bit Portability link ▶Code should be 64-bit and 32-bit fri
en
dly. Bear in mind problems of printing, comparisons, and structure alignm
en
t. printf() specifiers for some types are not cleanly portable betwe
en
32-bit and 64-bit systems. C99 defines some portable format specifiers. Unfortunately, MSVC 7.1 does not understand some of these specifiers and the standard is missing a few, so we have to define our own ugly versions in some cases (in the style of the standard include file inttypes.h): // printf macros for size_t, in the style of inttypes.h #ifdef _LP64 #define __PRIS_PREFIX "z" #else #define __PRIS_PREFIX #
en
dif // Use these macros after a % in a printf format string // to get correct 32/64 bit behavior, like this: // size_t size = records.size(); // printf("%"PRIuS"\n", size); #define PRIdS __PRIS_PREFIX "d" #define PRIxS __PRIS_PREFIX "x" #define PRIuS __PRIS_PREFIX "u" #define PRIXS __PRIS_PREFIX "X" #define PRIoS __PRIS_PREFIX "o" Type DO NOT use DO use Notes void * (or any pointer) %lx %p int64_t %qd, %lld %"PRId64" uint64_t %qu, %llu, %llx %"PRIu64", %"PRIx64" size_t %u %"PRIuS", %"PRIxS" C99 specifies %zu ptrdiff_t %d %"PRIdS" C99 specifies %zd Note that the PRI* macros expand to indep
en
d
en
t strings which are concat
en
ated by the compiler. H
en
ce if you are using a non-constant format string, you need to insert the value of the macro into the format, rather than the name. It is still possible, as usual, to include l
en
gth specifiers, etc., after the % wh
en
using the PRI* macros. So, e.g. printf("x = %30"PRIuS"\n", x) would expand on 32-bit Linux to printf("x = %30" "u" "\n", x), which the compiler will treat as printf("x = %30u\n", x). Remember that sizeof(void *) != sizeof(int). Use intptr_t if you want a pointer-sized integer. You may need to be careful with structure alignm
en
ts, particularly for structures being stored on disk. Any class/structure with a int64_t/uint64_t member will by default
en
d up being 8-byte aligned on a 64-bit system. If you have such structures being shared on disk betwe
en
32-bit and 64-bit code, you will need to
en
sure that they are packed the same on both architectures. Most compilers offer a way to alter structure alignm
en
t. For gcc, you can use __attribute__((packed)). MSVC offers #pragma pack() and __declspec(align()). Use the LL or ULL suffixes a
Stock Error
Error Code Error Message 10004 The operation is canceled. 10013 The requested
address
is a broadcast
address
, but flag is not set. 10014
Invalid
argum
en
t.
10022
Socket
not
bound
,
invalid
address
o
Socket
Exception.ErrorCode 的错误列表及注释,Win
socket
Error 列表及注释
注释是英文的,大家需要可以用翻译软件直接译,大体意思没问题。
WinSock Error Codes
The following error codes apply to the WinSock ActiveX Controls.
Error Code Error Message
10004 The operation is canceled.操作被取消
10013 The requested addres
ORA-02140 to ORA-04099错误速览
ORA-02140 to ORA-04099 ORA-02140:
invalid
tablespace name Cause: An id
en
tifier does not follow ALTER TABLESPACE. Action: Specify a tablespace name following ALTER TABLESPACE. ORA-0
Socket
Exception.ErrorCode 列表及注释,Win
socket
Error 列表及注释
WinSock Error Codes The following error codes apply to the WinSock ActiveX Controls. Error Code Error Message 10004 The operation is canceled.操作被取消 10013 The requested
address
is a broadcast ad...
网络编程
1,502
社区成员
18,432
社区内容
发帖
与我相关
我的任务
网络编程
VB 网络编程
复制链接
扫一扫
分享
社区描述
VB 网络编程
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章