Всех приветствую хотел адаптировать под свои нужды список из линукса (нужен в проекте на msvC) но вот незадача в половине макросов применяется typeof можно каждому макросу добавить параметр-тип тогда им можно будет заменить все typeof но в макросах и так по три параметра как сделать так чтоб это было меньшее из зол вот реализация списка list.h Код (Text): 1 #ifndef _LINUX_LIST_H 2 #define _LINUX_LIST_H 3 4 #include <linux/stddef.h> 5 #include <linux/poison.h> 6 #include <linux/prefetch.h> 7 #include <asm/system.h> 8 9 /* 10 * Simple doubly linked list implementation. 11 * 12 * Some of the internal functions ("__xxx") are useful when 13 * manipulating whole lists rather than single entries, as 14 * sometimes we already know the next/prev entries and we can 15 * generate better code by using them directly rather than 16 * using the generic single-entry routines. 17 */ 18 19 struct list_head { 20 struct list_head *next, *prev; 21 }; 22 23 #define LIST_HEAD_INIT(name) { &(name), &(name) } 24 25 #define LIST_HEAD(name) \ 26 struct list_head name = LIST_HEAD_INIT(name) 27 28 static inline void INIT_LIST_HEAD(struct list_head *list) 29 { 30 list->next = list; 31 list->prev = list; 32 } 33 34 /* 35 * Insert a new entry between two known consecutive entries. 36 * 37 * This is only for internal list manipulation where we know 38 * the prev/next entries already! 39 */ 40 #ifndef CONFIG_DEBUG_LIST 41 static inline void __list_add(struct list_head *new, 42 struct list_head *prev, 43 struct list_head *next) 44 { 45 next->prev = new; 46 new->next = next; 47 new->prev = prev; 48 prev->next = new; 49 } 50 #else 51 extern void __list_add(struct list_head *new, 52 struct list_head *prev, 53 struct list_head *next); 54 #endif 55 56 /** 57 * list_add - add a new entry 58 * @new: new entry to be added 59 * @head: list head to add it after 60 * 61 * Insert a new entry after the specified head. 62 * This is good for implementing stacks. 63 */ 64 static inline void list_add(struct list_head *new, struct list_head *head) 65 { 66 __list_add(new, head, head->next); 67 } 68 69 70 /** 71 * list_add_tail - add a new entry 72 * @new: new entry to be added 73 * @head: list head to add it before 74 * 75 * Insert a new entry before the specified head. 76 * This is useful for implementing queues. 77 */ 78 static inline void list_add_tail(struct list_head *new, struct list_head *head) 79 { 80 __list_add(new, head->prev, head); 81 } 82 83 /* 84 * Delete a list entry by making the prev/next entries 85 * point to each other. 86 * 87 * This is only for internal list manipulation where we know 88 * the prev/next entries already! 89 */ 90 static inline void __list_del(struct list_head * prev, struct list_head * next) 91 { 92 next->prev = prev; 93 prev->next = next; 94 } 95 96 /** 97 * list_del - deletes entry from list. 98 * @entry: the element to delete from the list. 99 * Note: list_empty() on entry does not return true after this, the entry is 100 * in an undefined state. 101 */ 102 #ifndef CONFIG_DEBUG_LIST 103 static inline void list_del(struct list_head *entry) 104 { 105 __list_del(entry->prev, entry->next); 106 entry->next = LIST_POISON1; 107 entry->prev = LIST_POISON2; 108 } 109 #else 110 extern void list_del(struct list_head *entry); 111 #endif 112 113 /** 114 * list_replace - replace old entry by new one 115 * @old : the element to be replaced 116 * @new : the new element to insert 117 * 118 * If @old was empty, it will be overwritten. 119 */ 120 static inline void list_replace(struct list_head *old, 121 struct list_head *new) 122 { 123 new->next = old->next; 124 new->next->prev = new; 125 new->prev = old->prev; 126 new->prev->next = new; 127 } 128 129 static inline void list_replace_init(struct list_head *old, 130 struct list_head *new) 131 { 132 list_replace(old, new); 133 INIT_LIST_HEAD(old); 134 } 135 136 /** 137 * list_del_init - deletes entry from list and reinitialize it. 138 * @entry: the element to delete from the list. 139 */ 140 static inline void list_del_init(struct list_head *entry) 141 { 142 __list_del(entry->prev, entry->next); 143 INIT_LIST_HEAD(entry); 144 } 145 146 /** 147 * list_move - delete from one list and add as another's head 148 * @list: the entry to move 149 * @head: the head that will precede our entry 150 */ 151 static inline void list_move(struct list_head *list, struct list_head *head) 152 { 153 __list_del(list->prev, list->next); 154 list_add(list, head); 155 } 156 157 /** 158 * list_move_tail - delete from one list and add as another's tail 159 * @list: the entry to move 160 * @head: the head that will follow our entry 161 */ 162 static inline void list_move_tail(struct list_head *list, 163 struct list_head *head) 164 { 165 __list_del(list->prev, list->next); 166 list_add_tail(list, head); 167 } 168 169 /** 170 * list_is_last - tests whether @list is the last entry in list @head 171 * @list: the entry to test 172 * @head: the head of the list 173 */ 174 static inline int list_is_last(const struct list_head *list, 175 const struct list_head *head) 176 { 177 return list->next == head; 178 } 179 180 /** 181 * list_empty - tests whether a list is empty 182 * @head: the list to test. 183 */ 184 static inline int list_empty(const struct list_head *head) 185 { 186 return head->next == head; 187 } 188 189 /** 190 * list_empty_careful - tests whether a list is empty and not being modified 191 * @head: the list to test 192 * 193 * Description: 194 * tests whether a list is empty _and_ checks that no other CPU might be 195 * in the process of modifying either member (next or prev) 196 * 197 * NOTE: using list_empty_careful() without synchronization 198 * can only be safe if the only activity that can happen 199 * to the list entry is list_del_init(). Eg. it cannot be used 200 * if another CPU could re-list_add() it. 201 */ 202 static inline int list_empty_careful(const struct list_head *head) 203 { 204 struct list_head *next = head->next; 205 return (next == head) && (next == head->prev); 206 } 207 208 /** 209 * list_rotate_left - rotate the list to the left 210 * @head: the head of the list 211 */ 212 static inline void list_rotate_left(struct list_head *head) 213 { 214 struct list_head *first; 215 216 if (!list_empty(head)) { 217 first = head->next; 218 list_move_tail(first, head); 219 } 220 } 221 222 /** 223 * list_is_singular - tests whether a list has just one entry. 224 * @head: the list to test. 225 */ 226 static inline int list_is_singular(const struct list_head *head) 227 { 228 return !list_empty(head) && (head->next == head->prev); 229 } 230 231 static inline void __list_cut_position(struct list_head *list, 232 struct list_head *head, struct list_head *entry) 233 { 234 struct list_head *new_first = entry->next; 235 list->next = head->next; 236 list->next->prev = list; 237 list->prev = entry; 238 entry->next = list; 239 head->next = new_first; 240 new_first->prev = head; 241 } 242 243 /** 244 * list_cut_position - cut a list into two 245 * @list: a new list to add all removed entries 246 * @head: a list with entries 247 * @entry: an entry within head, could be the head itself 248 * and if so we won't cut the list 249 * 250 * This helper moves the initial part of @head, up to and 251 * including @entry, from @head to @list. You should 252 * pass on @entry an element you know is on @head. @list 253 * should be an empty list or a list you do not care about 254 * losing its data. 255 * 256 */ 257 static inline void list_cut_position(struct list_head *list, 258 struct list_head *head, struct list_head *entry) 259 { 260 if (list_empty(head)) 261 return; 262 if (list_is_singular(head) && 263 (head->next != entry && head != entry)) 264 return; 265 if (entry == head) 266 INIT_LIST_HEAD(list); 267 else 268 __list_cut_position(list, head, entry); 269 } 270 271 static inline void __list_splice(const struct list_head *list, 272 struct list_head *prev, 273 struct list_head *next) 274 { 275 struct list_head *first = list->next; 276 struct list_head *last = list->prev; 277 278 first->prev = prev; 279 prev->next = first; 280 281 last->next = next; 282 next->prev = last; 283 } 284 285 /** 286 * list_splice - join two lists, this is designed for stacks 287 * @list: the new list to add. 288 * @head: the place to add it in the first list. 289 */ 290 static inline void list_splice(const struct list_head *list, 291 struct list_head *head) 292 { 293 if (!list_empty(list)) 294 __list_splice(list, head, head->next); 295 } 296 297 /** 298 * list_splice_tail - join two lists, each list being a queue 299 * @list: the new list to add. 300 * @head: the place to add it in the first list. 301 */ 302 static inline void list_splice_tail(struct list_head *list, 303 struct list_head *head) 304 { 305 if (!list_empty(list)) 306 __list_splice(list, head->prev, head); 307 } 308 309 /** 310 * list_splice_init - join two lists and reinitialise the emptied list. 311 * @list: the new list to add. 312 * @head: the place to add it in the first list. 313 * 314 * The list at @list is reinitialised 315 */ 316 static inline void list_splice_init(struct list_head *list, 317 struct list_head *head) 318 { 319 if (!list_empty(list)) { 320 __list_splice(list, head, head->next); 321 INIT_LIST_HEAD(list); 322 } 323 } 324 325 /** 326 * list_splice_tail_init - join two lists and reinitialise the emptied list 327 * @list: the new list to add. 328 * @head: the place to add it in the first list. 329 * 330 * Each of the lists is a queue. 331 * The list at @list is reinitialised 332 */ 333 static inline void list_splice_tail_init(struct list_head *list, 334 struct list_head *head) 335 { 336 if (!list_empty(list)) { 337 __list_splice(list, head->prev, head); 338 INIT_LIST_HEAD(list); 339 } 340 } 341 342 /** 343 * list_entry - get the struct for this entry 344 * @ptr: the &struct list_head pointer. 345 * @type: the type of the struct this is embedded in. 346 * @member: the name of the list_struct within the struct. 347 */ 348 #define list_entry(ptr, type, member) \ 349 container_of(ptr, type, member) 350 351 /** 352 * list_first_entry - get the first element from a list 353 * @ptr: the list head to take the element from. 354 * @type: the type of the struct this is embedded in. 355 * @member: the name of the list_struct within the struct. 356 * 357 * Note, that list is expected to be not empty. 358 */ 359 #define list_first_entry(ptr, type, member) \ 360 list_entry((ptr)->next, type, member) 361 362 /** 363 * list_for_each - iterate over a list 364 * @pos: the &struct list_head to use as a loop cursor. 365 * @head: the head for your list. 366 */ 367 #define list_for_each(pos, head) \ 368 for (pos = (head)->next; prefetch(pos->next), pos != (head); \ 369 pos = pos->next) 370 371 /** 372 * __list_for_each - iterate over a list 373 * @pos: the &struct list_head to use as a loop cursor. 374 * @head: the head for your list. 375 * 376 * This variant differs from list_for_each() in that it's the 377 * simplest possible list iteration code, no prefetching is done. 378 * Use this for code that knows the list to be very short (empty 379 * or 1 entry) most of the time. 380 */ 381 #define __list_for_each(pos, head) \ 382 for (pos = (head)->next; pos != (head); pos = pos->next) 383 384 /** 385 * list_for_each_prev - iterate over a list backwards 386 * @pos: the &struct list_head to use as a loop cursor. 387 * @head: the head for your list. 388 */ 389 #define list_for_each_prev(pos, head) \ 390 for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ 391 pos = pos->prev) 392 393 /** 394 * list_for_each_safe - iterate over a list safe against removal of list entry 395 * @pos: the &struct list_head to use as a loop cursor. 396 * @n: another &struct list_head to use as temporary storage 397 * @head: the head for your list. 398 */ 399 #define list_for_each_safe(pos, n, head) \ 400 for (pos = (head)->next, n = pos->next; pos != (head); \ 401 pos = n, n = pos->next) 402 403 /** 404 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry 405 * @pos: the &struct list_head to use as a loop cursor. 406 * @n: another &struct list_head to use as temporary storage 407 * @head: the head for your list. 408 */ 409 #define list_for_each_prev_safe(pos, n, head) \ 410 for (pos = (head)->prev, n = pos->prev; \ 411 prefetch(pos->prev), pos != (head); \ 412 pos = n, n = pos->prev) 413 414 /** 415 * list_for_each_entry - iterate over list of given type 416 * @pos: the type * to use as a loop cursor. 417 * @head: the head for your list. 418 * @member: the name of the list_struct within the struct. 419 */ 420 #define list_for_each_entry(pos, head, member) \ 421 for (pos = list_entry((head)->next, typeof(*pos), member); \ 422 prefetch(pos->member.next), &pos->member != (head); \ 423 pos = list_entry(pos->member.next, typeof(*pos), member)) 424 425 /** 426 * list_for_each_entry_reverse - iterate backwards over list of given type. 427 * @pos: the type * to use as a loop cursor. 428 * @head: the head for your list. 429 * @member: the name of the list_struct within the struct. 430 */ 431 #define list_for_each_entry_reverse(pos, head, member) \ 432 for (pos = list_entry((head)->prev, typeof(*pos), member); \ 433 prefetch(pos->member.prev), &pos->member != (head); \ 434 pos = list_entry(pos->member.prev, typeof(*pos), member)) 435 436 /** 437 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() 438 * @pos: the type * to use as a start point 439 * @head: the head of the list 440 * @member: the name of the list_struct within the struct. 441 * 442 * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). 443 */ 444 #define list_prepare_entry(pos, head, member) \ 445 ((pos) ? : list_entry(head, typeof(*pos), member)) 446 447 /** 448 * list_for_each_entry_continue - continue iteration over list of given type 449 * @pos: the type * to use as a loop cursor. 450 * @head: the head for your list. 451 * @member: the name of the list_struct within the struct. 452 * 453 * Continue to iterate over list of given type, continuing after 454 * the current position. 455 */ 456 #define list_for_each_entry_continue(pos, head, member) \ 457 for (pos = list_entry(pos->member.next, typeof(*pos), member); \ 458 prefetch(pos->member.next), &pos->member != (head); \ 459 pos = list_entry(pos->member.next, typeof(*pos), member)) 460 461 /** 462 * list_for_each_entry_continue_reverse - iterate backwards from the given point 463 * @pos: the type * to use as a loop cursor. 464 * @head: the head for your list. 465 * @member: the name of the list_struct within the struct. 466 * 467 * Start to iterate over list of given type backwards, continuing after 468 * the current position. 469 */ 470 #define list_for_each_entry_continue_reverse(pos, head, member) \ 471 for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ 472 prefetch(pos->member.prev), &pos->member != (head); \ 473 pos = list_entry(pos->member.prev, typeof(*pos), member)) 474 475 /** 476 * list_for_each_entry_from - iterate over list of given type from the current point 477 * @pos: the type * to use as a loop cursor. 478 * @head: the head for your list. 479 * @member: the name of the list_struct within the struct. 480 * 481 * Iterate over list of given type, continuing from current position. 482 */ 483 #define list_for_each_entry_from(pos, head, member) \ 484 for (; prefetch(pos->member.next), &pos->member != (head); \ 485 pos = list_entry(pos->member.next, typeof(*pos), member)) 486 487 /** 488 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry 489 * @pos: the type * to use as a loop cursor. 490 * @n: another type * to use as temporary storage 491 * @head: the head for your list. 492 * @member: the name of the list_struct within the struct. 493 */ 494 #define list_for_each_entry_safe(pos, n, head, member) \ 495 for (pos = list_entry((head)->next, typeof(*pos), member), \ 496 n = list_entry(pos->member.next, typeof(*pos), member); \ 497 &pos->member != (head); \ 498 pos = n, n = list_entry(n->member.next, typeof(*n), member)) 499 500 /** 501 * list_for_each_entry_safe_continue - continue list iteration safe against removal 502 * @pos: the type * to use as a loop cursor. 503 * @n: another type * to use as temporary storage 504 * @head: the head for your list. 505 * @member: the name of the list_struct within the struct. 506 * 507 * Iterate over list of given type, continuing after current point, 508 * safe against removal of list entry. 509 */ 510 #define list_for_each_entry_safe_continue(pos, n, head, member) \ 511 for (pos = list_entry(pos->member.next, typeof(*pos), member), \ 512 n = list_entry(pos->member.next, typeof(*pos), member); \ 513 &pos->member != (head); \ 514 pos = n, n = list_entry(n->member.next, typeof(*n), member)) 515 516 /** 517 * list_for_each_entry_safe_from - iterate over list from current point safe against removal 518 * @pos: the type * to use as a loop cursor. 519 * @n: another type * to use as temporary storage 520 * @head: the head for your list. 521 * @member: the name of the list_struct within the struct. 522 * 523 * Iterate over list of given type from current point, safe against 524 * removal of list entry. 525 */ 526 #define list_for_each_entry_safe_from(pos, n, head, member) \ 527 for (n = list_entry(pos->member.next, typeof(*pos), member); \ 528 &pos->member != (head); \ 529 pos = n, n = list_entry(n->member.next, typeof(*n), member)) 530 531 /** 532 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal 533 * @pos: the type * to use as a loop cursor. 534 * @n: another type * to use as temporary storage 535 * @head: the head for your list. 536 * @member: the name of the list_struct within the struct. 537 * 538 * Iterate backwards over list of given type, safe against removal 539 * of list entry. 540 */ 541 #define list_for_each_entry_safe_reverse(pos, n, head, member) \ 542 for (pos = list_entry((head)->prev, typeof(*pos), member), \ 543 n = list_entry(pos->member.prev, typeof(*pos), member); \ 544 &pos->member != (head); \ 545 pos = n, n = list_entry(n->member.prev, typeof(*n), member)) 546 547 /* 548 * Double linked lists with a single pointer list head. 549 * Mostly useful for hash tables where the two pointer list head is 550 * too wasteful. 551 * You lose the ability to access the tail in O(1). 552 */ 553 554 struct hlist_head { 555 struct hlist_node *first; 556 }; 557 558 struct hlist_node { 559 struct hlist_node *next, **pprev; 560 }; 561 562 #define HLIST_HEAD_INIT { .first = NULL } 563 #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } 564 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 565 static inline void INIT_HLIST_NODE(struct hlist_node *h) 566 { 567 h->next = NULL; 568 h->pprev = NULL; 569 } 570 571 static inline int hlist_unhashed(const struct hlist_node *h) 572 { 573 return !h->pprev; 574 } 575 576 static inline int hlist_empty(const struct hlist_head *h) 577 { 578 return !h->first; 579 } 580 581 static inline void __hlist_del(struct hlist_node *n) 582 { 583 struct hlist_node *next = n->next; 584 struct hlist_node **pprev = n->pprev; 585 *pprev = next; 586 if (next) 587 next->pprev = pprev; 588 } 589 590 static inline void hlist_del(struct hlist_node *n) 591 { 592 __hlist_del(n); 593 n->next = LIST_POISON1; 594 n->pprev = LIST_POISON2; 595 } 596 597 static inline void hlist_del_init(struct hlist_node *n) 598 { 599 if (!hlist_unhashed(n)) { 600 __hlist_del(n); 601 INIT_HLIST_NODE(n); 602 } 603 } 604 605 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 606 { 607 struct hlist_node *first = h->first; 608 n->next = first; 609 if (first) 610 first->pprev = &n->next; 611 h->first = n; 612 n->pprev = &h->first; 613 } 614 615 /* next must be != NULL */ 616 static inline void hlist_add_before(struct hlist_node *n, 617 struct hlist_node *next) 618 { 619 n->pprev = next->pprev; 620 n->next = next; 621 next->pprev = &n->next; 622 *(n->pprev) = n; 623 } 624 625 static inline void hlist_add_after(struct hlist_node *n, 626 struct hlist_node *next) 627 { 628 next->next = n->next; 629 n->next = next; 630 next->pprev = &n->next; 631 632 if(next->next) 633 next->next->pprev = &next->next; 634 } 635 636 /* 637 * Move a list from one list head to another. Fixup the pprev 638 * reference of the first entry if it exists. 639 */ 640 static inline void hlist_move_list(struct hlist_head *old, 641 struct hlist_head *new) 642 { 643 new->first = old->first; 644 if (new->first) 645 new->first->pprev = &new->first; 646 old->first = NULL; 647 } 648 649 #define hlist_entry(ptr, type, member) container_of(ptr,type,member) 650 651 #define hlist_for_each(pos, head) \ 652 for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ 653 pos = pos->next) 654 655 #define hlist_for_each_safe(pos, n, head) \ 656 for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ 657 pos = n) 658 659 /** 660 * hlist_for_each_entry - iterate over list of given type 661 * @tpos: the type * to use as a loop cursor. 662 * @pos: the &struct hlist_node to use as a loop cursor. 663 * @head: the head for your list. 664 * @member: the name of the hlist_node within the struct. 665 */ 666 #define hlist_for_each_entry(tpos, pos, head, member) \ 667 for (pos = (head)->first; \ 668 pos && ({ prefetch(pos->next); 1;}) && \ 669 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ 670 pos = pos->next) 671 672 /** 673 * hlist_for_each_entry_continue - iterate over a hlist continuing after current point 674 * @tpos: the type * to use as a loop cursor. 675 * @pos: the &struct hlist_node to use as a loop cursor. 676 * @member: the name of the hlist_node within the struct. 677 */ 678 #define hlist_for_each_entry_continue(tpos, pos, member) \ 679 for (pos = (pos)->next; \ 680 pos && ({ prefetch(pos->next); 1;}) && \ 681 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ 682 pos = pos->next) 683 684 /** 685 * hlist_for_each_entry_from - iterate over a hlist continuing from current point 686 * @tpos: the type * to use as a loop cursor. 687 * @pos: the &struct hlist_node to use as a loop cursor. 688 * @member: the name of the hlist_node within the struct. 689 */ 690 #define hlist_for_each_entry_from(tpos, pos, member) \ 691 for (; pos && ({ prefetch(pos->next); 1;}) && \ 692 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ 693 pos = pos->next) 694 695 /** 696 * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry 697 * @tpos: the type * to use as a loop cursor. 698 * @pos: the &struct hlist_node to use as a loop cursor. 699 * @n: another &struct hlist_node to use as temporary storage 700 * @head: the head for your list. 701 * @member: the name of the hlist_node within the struct. 702 */ 703 #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ 704 for (pos = (head)->first; \ 705 pos && ({ n = pos->next; 1; }) && \ 706 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ 707 pos = n) 708 709 #endif 710
Напиши на C++ то же самое. Причём начни с STL, я думаю, что играясь с параметризованными типами из STL можно получить циклический двусвязный список с принудительной связью и с заголовком. Или выкини все list_for_each_entry*. Вполне можно обойтись без них.
osox Не стоит заморачиваться, ядро использует много gcc расширений. Возьмите какую-нибудь библиотеку контейнеров для Cи, libscl к примеру.
Спасибо за ответы r90 так и сделал выкинул экзотику на основе list_for_each_entry и иже с ними а что понадобится допишем пришлось удалить prefetch в некоторых макросах оптимизация была ну и container_of заменил на вендовый CONTAINING_RECORD Booster собрал потестил у меня обычно GLIB да GDSL под рукой на венде GLIB использую когда для себя что нибудь пишу быстро удобно GDSL деревья CURL интернет оброс библиотками ну и теперь LIBSCL собрал как статик либу но я специально хотел интрузивный список а в этих либах совсем другая реализация
green у меня на С код Код (Text): int main(void) { int i; decltype(i) j; return 0; } Compile as C Code(/TC) 'decltype' undefined; assuming extern returning int он считает его за идентификатор функции а gcc это компилит нормально Код (Text): int main(void) { int i; typeof(i) j; return 0; } вот если бы для С аналог typeof был
J0E - ёжик тужился, пыхтел - но всё равно пёр на себе два плюса. А то как же, в наше время без плюсов не модно. Что ты за ёжик если плюсов не притянул, а одни яблоки
Какие причины использовать /TC кроме упертости? Все равно typeof уже отказ от С. Знания не утяжеляют мозг) Не осилил сам -- помолчи.
При чём здесь осилил/не осилил? Человек что, спрашивал на чём ему писать? По-моему очевидно что пишет он на Си, и совет ему нужен с учётом этого. С таким же успехом мог бы Javascript посоветовать - там typeof есть.
Все ж задам. Сходил, там поля ввода и 2 кнопки. Что делать дальше? Очевидно что он использует на MSVC, то есть платформу не имеющую проблем с С++
К счастью, я не приучен добиваться результата сниманием штанов. Всегда есть другие способы. Поэтому не понятно какие проблемы у твоего первого совета, или №5. ЗЫ Специально для тех кому очевидно использование С привожу список его ключевых слов, очнитесь: auto break case char const continue default do double else enum extern float for goto if inline int long register restrict return short signed sizeof static struct switch typedef union unsigned void volatile while _Bool _Complex _Imaginary
J0E Я был прав, ты не готов принимать информацию. Ты пришёл сюда доказывать свою оффтопичную правоту, но уши твои закрыты, ты не услышишь меня, даже если я переборю свою лень, и нырну в предлагаемый тобою холивар.
Написать киворды для гугла занимает меньше времени, чем сочинять про якобы правоту (где ты утверждал о моей неготовности?) так что не надо обманывать(ся) ленью. И не надо приписывать мне разжигание холиваров, мне эти споры совершенно не интересны, я неплохо понимаю разницу между языками и вряд ли узнаю в результате что-то новое. Если на кого-то ++ действует как красная тряпка -- так нечо на зеркало пенять, я называю это упертостью и некомпетентностью поскольку сам через это прошел и знаю что кто-то в результате шоковой терапии чему-то научится, а кому не дано так что ж. Еще я видел приличные С библиотеки которые вполне нормально собиралиcь с /TP потому что авторы задумывались о портабельности и писали явные касты от void*. Вот мне и неясно желание ограничивать себя /TC (рантайм поддержка для требуемой фичи не требуется). Если бы автор темы написал "мне нельзя использовать новую студию" я бы молча прошел мимо. В скрываемой тобой информации ничего секретного нет, мог бы оставить ее для других, ведь форум публичный, какой смысл учить единственного персонажа, не несущего дезинформацию?
J0E Ты упорен. Это хорошее качество. Но, ты ошибаешься, считая что я обязан нести свет в массы. Я сложил эту задачу с себя, уже почти год назад. Кроме того, этот топик не требует продолжения: те кто хотел знать ответы на твои вопросы, уже узнали в гугле. Те кто знать не хотел, не узнают, чтобы я здесь не написал. J0E Ты не прав. Перечитай топик. Два раза. Или столько раз, сколько потребуется для просветления. Прочитал? Просветление пришло? А теперь я открою тебе более глубокую мудрость. Подумай о том, что случится, если я соберу аргументы из гугла и изложу их здесь. Подумай, и согласись с тем, что увидев аргументы, ты сочтёшь своим долгом их все опровергнуть. Согласись также с тем, что придёт ещё парочка человек, и тоже начнёт опровергать. Потом придёт ещё три человека и начнут опровергать опровержения. Вы же начнёте опровергать опровержения опровержений. И так далее... До бесконечности. То есть тут будет холивар. Так? А кто будет виновником этого холивара? Ты, не так ли? Ведь это ты убеждаешь меня начать рассказывать тут о преимуществах C.